<!DOCTYPE html>


  <html class="dark page-post">


<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>node基础篇回顾 | Poetry&#39;s Blog</title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  
    <meta name="keywords" content="JavaScript,Node,">
  

  <meta name="description" content="一、nodejs介绍1.1 简介 nodejs是一个JavaScript运行环境。它让 JavaScript 可以开发后端程序，实现几乎其他后端语言实现的所有功能 Nodejs 是基于 V8 引擎，V8 是 Google 发布的开源 JavaScript 引擎，本身就是用于 Chrome 浏览器 的 JS 解释部分， V8 搬到了服务器上，用于做服务器的软件 短短几年的时间，Node 取得了巨大的">
<meta name="keywords" content="JavaScript,Node">
<meta property="og:type" content="article">
<meta property="og:title" content="node基础篇回顾">
<meta property="og:url" content="http://blog.poetries.top/2019/03/09/node-base-review/index.html">
<meta property="og:site_name" content="Poetry&#39;s Blog">
<meta property="og:description" content="一、nodejs介绍1.1 简介 nodejs是一个JavaScript运行环境。它让 JavaScript 可以开发后端程序，实现几乎其他后端语言实现的所有功能 Nodejs 是基于 V8 引擎，V8 是 Google 发布的开源 JavaScript 引擎，本身就是用于 Chrome 浏览器 的 JS 解释部分， V8 搬到了服务器上，用于做服务器的软件 短短几年的时间，Node 取得了巨大的">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/356.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/357.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/358.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/359.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/360.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/361.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/362.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/363.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/364.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/365.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/366.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/367.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/368.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/369.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/370.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/371.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/372.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/373.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/374.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/375.png">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1480597-450216a694af3946.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/376.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/377.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/378.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/379.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/380.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/381.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/382.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/383.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/384.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/385.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/386.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/387.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/388.png">
<meta property="og:updated_time" content="2020-08-15T04:25:31.930Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="node基础篇回顾">
<meta name="twitter:description" content="一、nodejs介绍1.1 简介 nodejs是一个JavaScript运行环境。它让 JavaScript 可以开发后端程序，实现几乎其他后端语言实现的所有功能 Nodejs 是基于 V8 引擎，V8 是 Google 发布的开源 JavaScript 引擎，本身就是用于 Chrome 浏览器 的 JS 解释部分， V8 搬到了服务器上，用于做服务器的软件 短短几年的时间，Node 取得了巨大的">
<meta name="twitter:image" content="https://poetries1.gitee.io/img-repo/2019/10/356.png">

  

  
    <link rel="icon" href="/favicon.ico">
  

  <link href="/css/styles.css?v=c114cbeddx" rel="stylesheet">
<link href="/css/other.css?v=c114cbeddx" rel="stylesheet">


  
    <link rel="stylesheet" href="/css/personal-style.css">
  

  

  
  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?40b1f89aa80f2527b3db779c6898c879";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>


  
  <script type="text/javascript">
	(function(){
	    var bp = document.createElement('script');
	    var curProtocol = window.location.protocol.split(':')[0];
	    if (curProtocol === 'https') {
	        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
	    }
	    else {
	        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
	    }
	    var s = document.getElementsByTagName("script")[0];
	    s.parentNode.insertBefore(bp, s);
	})();
  </script>



  
    <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.3.0/css/font-awesome.min.css">
  

  <!-- 聊天系统 -->
  
    
   <link type="text/css" rel="stylesheet" href="/renxi/default.css">
   <style>
      #modal {
        position: static !important;
      }
      .filter {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
        background: #fe5757;
        animation: colorChange 30s ease-in-out infinite;
        animation-fill-mode: both;
        mix-blend-mode: overlay;
      }
  
      @keyframes colorChange {
        0%, 100% {
            opacity: 0;
        }
        50% {
            opacity: .9;
        }
      }
   </style>
</head>
</html>
<body>
  
  
    <span id="toolbox-mobile" class="toolbox-mobile">导航</span>
  

  <div class="post-header CENTER">
   
  <div class="toolbox">
    <a class="toolbox-entry" href="/">
      <span class="toolbox-entry-text">导航</span>
      <i class="icon-angle-down"></i>
      <i class="icon-home"></i>
    </a>
    <ul class="list-toolbox">
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/archives/"
            rel="noopener noreferrer"
            target="_self"
            >
            博客
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/categories/"
            rel="noopener noreferrer"
            target="_self"
            >
            分类
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/tags/"
            rel="noopener noreferrer"
            target="_self"
            >
            标签
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/search/"
            rel="noopener noreferrer"
            target="_self"
            >
            搜索
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/link/"
            rel="noopener noreferrer"
            target="_self"
            >
            友链
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/about/"
            rel="noopener noreferrer"
            target="_self"
            >
            关于
          </a>
        </li>
      
    </ul>
  </div>


</div>


  <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录<i class="iconfont toc-title" style="display:inline-block;color:#87998d;width:20px;height:20px;">&#xf004b;</i></strong>
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#一、nodejs介绍"><span class="toc-text">一、nodejs介绍</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-1-简介"><span class="toc-text">1.1 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-2-NodeJs-的优势"><span class="toc-text">1.2 NodeJs 的优势</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-3-NodeJs-适合做什么"><span class="toc-text">1.3 NodeJs 适合做什么</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#二、HTTP模块、URL模块-supervisor工具"><span class="toc-text">二、HTTP模块、URL模块 supervisor工具</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#2-1-创建一个简单的程序"><span class="toc-text">2.1 创建一个简单的程序</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-2-HTTP-模块、URL模块"><span class="toc-text">2.2 HTTP 模块、URL模块</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-1、HTTP-模块的使用"><span class="toc-text">2.2.1、HTTP 模块的使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-2、URL-模块的使用"><span class="toc-text">2.2.2、URL 模块的使用</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-3-Nodejs-自启动工具-supervisor"><span class="toc-text">2.3 Nodejs 自启动工具 supervisor</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#三、CommonJs-和-Nodejs-模块"><span class="toc-text">三、CommonJs 和 Nodejs 模块</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#3-1-什么是-CommonJs"><span class="toc-text">3.1 什么是 CommonJs</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-2-Nodejs-中的模块化"><span class="toc-text">3.2 Nodejs 中的模块化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-1-在-Node-中，模块分为两类"><span class="toc-text">3.2.1 在 Node 中，模块分为两类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-2-CommonJS-Nodejs-中自定义模块的规定"><span class="toc-text">3.2.2 CommonJS(Nodejs)中自定义模块的规定</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-3-定义使用模块"><span class="toc-text">3.2.3 定义使用模块</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#四、NPM第三方模块和package"><span class="toc-text">四、NPM第三方模块和package</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#4-1-包与-NPM"><span class="toc-text">4.1 包与 NPM</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#4-1-1-包"><span class="toc-text">4.1.1 包</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-1-2-NPM-介绍"><span class="toc-text">4.1.2 NPM 介绍</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-2-package-json"><span class="toc-text">4.2 package.json</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-3-安装淘宝镜像"><span class="toc-text">4.3 安装淘宝镜像</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#五、fs模块"><span class="toc-text">五、fs模块</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#5-1-fs-stat-检测是文件还是目录"><span class="toc-text">5.1 fs.stat 检测是文件还是目录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-2-fs-mkdir-创建目录"><span class="toc-text">5.2 fs.mkdir 创建目录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-3-fs-writeFile-创建写入文件"><span class="toc-text">5.3 fs.writeFile 创建写入文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-4-fs-appendFile-追加文件"><span class="toc-text">5.4 fs.appendFile 追加文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-5-fs-readFile-读取文件"><span class="toc-text">5.5 fs.readFile 读取文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-6-fs-readdir-读取目录"><span class="toc-text">5.6 fs.readdir 读取目录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-7-fs-rename-重命名"><span class="toc-text">5.7 fs.rename 重命名</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-8-fs-rmdir-删除目录"><span class="toc-text">5.8 fs.rmdir 删除目录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-9-fs-unlink-删除文件"><span class="toc-text">5.9 fs.unlink 删除文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-10-fs-createReadStream-从文件流中读取数据"><span class="toc-text">5.10 fs.createReadStream 从文件流中读取数据</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-11-fs-createWriteStream-写入文件"><span class="toc-text">5.11 fs.createWriteStream 写入文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-12-管道流"><span class="toc-text">5.12 管道流</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#六、创建一个-WEB-服务器"><span class="toc-text">六、创建一个 WEB 服务器</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#七、Nodejs-的非阻塞-I-O、异步、事件驱动"><span class="toc-text">七、Nodejs 的非阻塞 I/O、异步、事件驱动</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#7-1-Nodejs的单线程-非阻塞I-O事件驱动"><span class="toc-text">7.1 Nodejs的单线程 非阻塞I/O事件驱动</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-2-Nodejs-回调处理异步"><span class="toc-text">7.2 Nodejs 回调处理异步</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-3-Nodejs-events-模块处理异步"><span class="toc-text">7.3 Nodejs events 模块处理异步</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#八、静态文件托管-GET-POST路由EJS模板引擎"><span class="toc-text">八、静态文件托管 GET POST路由EJS模板引擎</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#8-1-路由"><span class="toc-text">8.1 路由</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#8-2-初识-EJS-模块引擎"><span class="toc-text">8.2 初识 EJS 模块引擎</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#8-3-Get、Post"><span class="toc-text">8.3 Get、Post</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#九、MongoDb-数据库介绍、安装、使用"><span class="toc-text">九、MongoDb 数据库介绍、安装、使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#9-1-数据库和文件的主要区别"><span class="toc-text">9.1 数据库和文件的主要区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-2-NoSql-介绍"><span class="toc-text">9.2 NoSql 介绍</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#9-2-1-NoSQL-介绍"><span class="toc-text">9.2.1 NoSQL 介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#9-2-2-NoSQL-应用情况介绍"><span class="toc-text">9.2.2 NoSQL 应用情况介绍</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-3-什么时候建议使用-NoSql"><span class="toc-text">9.3 什么时候建议使用 NoSql</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-4-NoSql-和传统数据库简单对比"><span class="toc-text">9.4 NoSql 和传统数据库简单对比</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-5-NoSql-种类"><span class="toc-text">9.5 NoSql 种类</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-6-MongoDb-介绍"><span class="toc-text">9.6 MongoDb 介绍</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-7-MongoDb-安装"><span class="toc-text">9.7 MongoDb 安装</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-8-使用-MongoDb"><span class="toc-text">9.8 使用 MongoDb</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十、MongoDB-数据库创建删除、表（集合）创建删除、数据增删改查"><span class="toc-text">十、MongoDB 数据库创建删除、表（集合）创建删除、数据增删改查</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#10-1-数据库使用"><span class="toc-text">10.1 数据库使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10-2-创建数据库"><span class="toc-text">10.2 创建数据库</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10-3-插入-增加-数据"><span class="toc-text">10.3 插入(增加)数据</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10-4-查找数据"><span class="toc-text">10.4 查找数据</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10-5-修改数据"><span class="toc-text">10.5 修改数据</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10-6-删除数据"><span class="toc-text">10.6 删除数据</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十一、MongoDB-索引-explain-分析查询速度"><span class="toc-text">十一、MongoDB 索引 explain 分析查询速度</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#11-1-索引基础"><span class="toc-text">11.1 索引基础</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11-2-唯一索引"><span class="toc-text">11.2 唯一索引</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11-3-索引的一些参数"><span class="toc-text">11.3 索引的一些参数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11-4-使用-explain"><span class="toc-text">11.4 使用 explain</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11-5-explain-executionStats-查询具体的执行-时间"><span class="toc-text">11.5 explain executionStats 查询具体的执行 时间</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十二、nodejs操作mongodb3-x数据库的方法"><span class="toc-text">十二、nodejs操作mongodb3.x数据库的方法</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十三、NodeJs操作MongoDb数据库-数据的增加-修改-删除"><span class="toc-text">十三、NodeJs操作MongoDb数据库 数据的增加 修改 删除</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#13-1-在-Nodejs-中使用-Mongodb"><span class="toc-text">13.1 在 Nodejs 中使用 Mongodb</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-2-Nodejs-连接-MongoDb-数据库"><span class="toc-text">13.2 Nodejs 连接 MongoDb 数据库</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-3-Nodejs-查找-MongoDb-数据库集合"><span class="toc-text">13.3 Nodejs 查找 MongoDb 数据库集合</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-4-Nodejs-给-MongoDb-增加数据"><span class="toc-text">13.4 Nodejs 给 MongoDb 增加数据</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-5-Nodejs-修改-MongoDb-数据"><span class="toc-text">13.5 Nodejs 修改 MongoDb 数据</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-6-Nodejs-删除-MongoDb-数据"><span class="toc-text">13.6 Nodejs 删除 MongoDb 数据</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十四、Express-安装和使用"><span class="toc-text">十四、Express 安装和使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#14-1-Express-简单介绍"><span class="toc-text">14.1 Express 简单介绍</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#14-2-Express-安装使用"><span class="toc-text">14.2 Express 安装使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#14-3-Express-框架中的路由"><span class="toc-text">14.3 Express 框架中的路由</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#14-4-Express-框架中-ejs-的安装使用"><span class="toc-text">14.4 Express 框架中 ejs 的安装使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#14-5-利用-Express-static-托管静态文件"><span class="toc-text">14.5 利用 Express.static 托管静态文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#14-6-Express-中间件"><span class="toc-text">14.6 Express 中间件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#14-7-获取-Get-Post-请求的参数"><span class="toc-text">14.7 获取 Get Post 请求的参数</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十五、express中间件cookie的基本使用"><span class="toc-text">十五、express中间件cookie的基本使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#15-1-Cookie-简介"><span class="toc-text">15.1 Cookie 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#15-2-Cookie-特点"><span class="toc-text">15.2 Cookie 特点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#15-3-Cookie-的使用"><span class="toc-text">15.3 Cookie 的使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#15-4-加密-Cookie"><span class="toc-text">15.4 加密 Cookie</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十六、express中间件express-session常见参数配置使用"><span class="toc-text">十六、express中间件express-session常见参数配置使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#16-1-Session-简单介绍"><span class="toc-text">16.1 Session 简单介绍</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#16-2-Session-的工作流程"><span class="toc-text">16.2 Session 的工作流程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#16-3-express-session-的使用"><span class="toc-text">16.3 express-session 的使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#16-4-express-session-的常用参数"><span class="toc-text">16.4 express-session 的常用参数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#16-5-express-session-的常用方法"><span class="toc-text">16.5 express-session 的常用方法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#16-6-负载均衡配置-Session，把-Session-保存到数据库-里面"><span class="toc-text">16.6 负载均衡配置 Session，把 Session 保存到数据库 里面</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#16-7-Cookie-和-Session-区别"><span class="toc-text">16.7 Cookie 和 Session 区别</span></a></li></ol></li></ol>
  </div>
  




<div class="content content-post CENTER">
   <!-- canvas 彩带 -->
<canvas id="evanyou" width="1302" height="678" style="position: fixed;width: 100%;height: 100%;top: 0;left:0;z-index:-1;"></canvas>

<article id="post-node-base-review" class="article article-type-post" itemprop="blogPost">
  <header class="article-header" style="position:relative;">
    <h1 class="post-title">node基础篇回顾</h1>

    <div class="article-meta">
      <span>
        <i class="icon-calendar"></i>
        <span>2019.03.09</span>
      </span>

      
        <span class="article-author">
          <i class="icon-user"></i>
          <span>Poetry</span>
        </span>
      

      
  <span class="article-category">
    <i class="icon-list"></i>
    <a class="article-category-link" href="/categories/Back-end/">Back-end</a>
  </span>



      

      
      <i class="fa fa-eye"></i> 
        <span id="busuanzi_container_page_pv">
           &nbsp热度 <span id="busuanzi_value_page_pv">
           <i class="fa fa-spinner fa-spin"></i></span>℃
        </span>
      
      
       
          <span class="post-count">
            <i class="fa fa-file-word-o"></i>&nbsp
            <span>字数统计 12.9k字</span>
          </span>

          <span class="post-count">
            <i class="fa fa-columns"></i>&nbsp
            <span>阅读时长 53分</span>
          </span>
      
      
    </div>

    <i class="iconfont" id="toc-eye" style="display:inline-block;color:#b36619;position:absolute;top:0;right:0;cursor:pointer;
    font-size: 24px;">&#xe61c;</i>

  </header>

  <div class="article-content">
    
      <div id="container">
        <h1 id="一、nodejs介绍"><a href="#一、nodejs介绍" class="headerlink" title="一、nodejs介绍"></a>一、nodejs介绍</h1><h2 id="1-1-简介"><a href="#1-1-简介" class="headerlink" title="1.1 简介"></a>1.1 简介</h2><ul>
<li><code>nodejs</code>是一个<code>JavaScript</code>运行环境。它让 <code>JavaScript</code> 可以开发后端程序，实现几乎其他后端语言实现的所有功能</li>
<li><code>Nodejs</code> 是基于 <code>V8</code> 引擎，<code>V8</code> 是 <code>Google</code> 发布的开源 <code>JavaScript</code> 引擎，本身就是用于 <code>Chrome</code> 浏览器 的 <code>JS</code> 解释部分， <code>V8</code> 搬到了服务器上，用于做服务器的软件</li>
<li>短短几年的时间，Node 取得了巨大的成功。在企业界，Node 的应用也越来越广泛，2016 年 nodeJS 官方的调查报告。2016 年全球有 350 万开发者使用 nodeJS,相比去年保持了 100%的增长率。像 Yahoo、 Microsoft 这样的大公司，有好多应用已经迁移到 Node 了。国内的阿里巴巴、网易、腾讯、新浪、百度等 公司的很多线上产品也纷纷改用 Node 开发，并取得了很好的效果。据统计很多 A 轮、 B 轮的创业公司更 喜欢使用 NodeJs 开发。</li>
</ul>
<blockquote>
<p><a href="https://nodejs.org/static/documents/2016-survey-report.pdf" target="_blank" rel="noopener">https://nodejs.org/static/documents/2016-survey-report.pdf</a></p>
</blockquote>
<h2 id="1-2-NodeJs-的优势"><a href="#1-2-NodeJs-的优势" class="headerlink" title="1.2 NodeJs 的优势"></a>1.2 NodeJs 的优势</h2><p><strong>1. NodeJs 语法完全是 js 语法，只要你懂 JS 基础就可以学会 Nodejs 后端开发</strong></p>
<blockquote>
<p>Node 打破了过去 JavaScript 只能在浏览器中运行的局面。前后端编程环境统一，可以大大降低开发成本</p>
</blockquote>
<p><strong>2. NodeJs 超强的高并发能力</strong></p>
<ul>
<li><code>Node.js</code> 的首要目标是提供一种简单的、用于创建高性能服务器及可在该服务器中运行的各种应用程 序的开发工具</li>
<li>首先让我们来看一下现在的服务器端语言中存在着什么问题。<br>在 <code>Java</code>、<code>PHP</code> 或者<code>.net</code> 等服务器端语言中，会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约 <code>2MB</code> 内存<br>理论上，一个 <code>8GB</code> 内存的服务器可以同时连接的最大用户数为 <code>4000</code> 个左右<br>。要让 <code>Web</code> 应用程序支持更多的用户，就 需要增加服务器的数量，而 <code>Web</code> 应用程序的硬件成本当然就上升了</li>
<li><code>Node.js</code> 不为每个客户连接创建一个新的线程，而仅仅使用一个线程。当有用户连接了，就触发一个 内部事件，通过非阻塞 <code>I/O</code>、事件驱动机制，让 <code>Node.js</code> 程序宏观上也是并行的。使用 <code>Node.js</code>，一个 <code>8GB</code> 内存的服务器，可以同时处理超过 <code>4 万</code>用户的连接</li>
</ul>
<p><strong>3. 实现高性能服务器</strong></p>
<ul>
<li>严格地说，<code>Node.js</code> 是一个用于开发各种 Web 服务器的开发工具。在 <code>Node.js</code> 服务器中，运行的是高性能 <code>V8 JavaScript</code> 脚本语言，该语言是一种可以运行在服务器端的 <code>JavaScript</code> 脚本语言</li>
<li>那么，什么是 <code>V8 JavaScript</code> 脚本语言呢?该语言是一种被 <code>V8 JavaScript</code> 引擎所解析并执行的脚本语言。<code>V8 JavaScript</code> 引擎是由 <code>Google</code> 公司使用 C++语言开发的一种高性能 <code>JavaScript</code> 引擎，该引擎并不局限于在浏览 器中运行。<code>Node.js</code> 将其转用在了服务器中，并且为其提供了许多附加的具有各种不同用途的 <code>API</code>。例如， 在一个服务器中，经常需要处理各种二进制数据。在 <code>JavaScript</code> 脚本语言中，只具有非常有限的对二进制数 据的处理能力，而 <code>Node.js</code> 所提供的 <code>Buffer</code> 类则提供了丰富的对二进制数据的处理能力</li>
<li>另外，在 <code>V8 JavaScript</code>引擎内部使用一种全新的编译技术。这意味着开发者编写的高端的 <code>JavaScript</code> 脚本代码与开发者编写的低端的C语言具有非常相近的执行效率，这也是<code>Node.js</code>服务器可以提供的一个重要特性</li>
</ul>
<p><strong>4. 开发周期短、开发成本低、学习成本低。</strong></p>
<ul>
<li><code>Node.js</code> 自身哲学，是花最小的硬件成本，追求更高的并发，更高的处理性能。</li>
<li>特点:<code>Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.</code></li>
</ul>
<h2 id="1-3-NodeJs-适合做什么"><a href="#1-3-NodeJs-适合做什么" class="headerlink" title="1.3 NodeJs 适合做什么"></a>1.3 NodeJs 适合做什么</h2><blockquote>
<p>在短短几年多的时间里，<code>Node</code> 变得非常热门，使用者也非常多。这些使用者对于 <code>Node</code> 的各自倚重点也各部相同，经过整理,主要有下几类</p>
</blockquote>
<p><strong>1. 前后端编程语言环境统一</strong></p>
<blockquote>
<p>这类重点的代表是雅虎。雅虎开放了 <code>Cocktai</code> 框架，利用 自己深厚的前端沉淀，将 <code>YUI3</code> 这个前端框架的能力借助 <code>Node</code> 延伸到服务器端，使得使用 者摆脱了日常工作中一边写 <code>JavaScript</code> —边写 <code>PHP</code> 所帯来的上下文交换负担</p>
</blockquote>
<p><strong>2. Node 带来的高性能 I/0 用于实时应用</strong></p>
<blockquote>
<p><code>Voxer</code> 将 <code>Node</code> 应用在实时语音上。国内腾讯的 朋友网将 Node 应用在长连接中，以提供实时功能，花瓣网、蘑菇街等公司通过 <code>socket.io</code> 实 现实时通知的功能。</p>
</blockquote>
<p><strong>3. 并行 I/0 使得使用者可以更高效地利用分布式环境</strong></p>
<blockquote>
<p>阿里巴巴 eBay 是这方面的典型。 阿里巴巴的 NodeFox 和 eBay 的 ql.io 都是借用 Node 并行 I/O 的能力，更高效地使用已有的 数据</p>
</blockquote>
<p><strong>4. 并行 I/O •有效利用稳定接口提升 Web 渲染能力</strong></p>
<blockquote>
<p>雪球财经和 Linkedln 的移动版网站均 是这种案例，撇弃 同步等待式的顺序请求，大胆采用并行丨/〇，加速数据的获取进而提升 Web 的渲染速度</p>
</blockquote>
<p><strong>5. 云计算平台提供 Node 支持</strong></p>
<blockquote>
<p>微软将 Node 引入 Azure 的开发中，阿里云、百度均纷纷 在云服务器上提供 Node 应用托管服务，Joyent 更是云计算中提供 Node 支持的代表。这类 平台看重 JavaScript 带来的开发上的优势，以及低资源占用、高性能的特点</p>
</blockquote>
<p><strong>6. 游戏开发领域</strong></p>
<blockquote>
<p>游戏领域对实时和并发有很高的要求，网易开源了 pomelo 实时框架， 可以应用在游戏和高实时应用中</p>
</blockquote>
<p><strong>7. 工具类应用</strong></p>
<blockquote>
<p>过去依赖 <code>java</code> 或其他语言构建的前端工具类应用，纷纷被一些前端工程 师用 <code>Node</code> 重写，用前端熟悉的语言为前端构建熟悉的工具</p>
</blockquote>
<h1 id="二、HTTP模块、URL模块-supervisor工具"><a href="#二、HTTP模块、URL模块-supervisor工具" class="headerlink" title="二、HTTP模块、URL模块 supervisor工具"></a>二、HTTP模块、URL模块 supervisor工具</h1><blockquote>
<p>用 <code>Node.js</code> 时，我们不仅仅在实现一个应用，同时还实现了整个 <code>HTTP</code> 服务器</p>
</blockquote>
<h2 id="2-1-创建一个简单的程序"><a href="#2-1-创建一个简单的程序" class="headerlink" title="2.1 创建一个简单的程序"></a>2.1 创建一个简单的程序</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">'http'</span>);</span><br><span class="line"></span><br><span class="line">http.createServer(<span class="function"><span class="keyword">function</span>(<span class="params">request, response</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 发送 HTTP 头部</span></span><br><span class="line">    <span class="comment">// HTTP 状态值: 200 : OK</span></span><br><span class="line">    <span class="comment">//设置 HTTP 头部，状态码是 200，文件类型是 html，字符集是 utf8 response.writeHead(200,&#123;"Content-Type":"text/html;charset=UTF-8"&#125;);</span></span><br><span class="line">    <span class="comment">// 发送响应数据 "Hello World"</span></span><br><span class="line">    res.end(<span class="string">"哈哈哈哈，我买了一个 iPhone"</span> + (<span class="number">1</span> + <span class="number">2</span> + <span class="number">3</span>) + <span class="string">"s"</span>);</span><br><span class="line">&#125;).listen(<span class="number">8888</span>);</span><br><span class="line"><span class="comment">// 终端打印如下信息</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'Server running at http://127.0.0.1:8888/'</span>);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>你会发现，我们本地写一个 <code>js</code>，打死都不能直接拖入浏览器运行，但是有了 <code>node</code>，我 们任何一个 <code>js</code> 文件，都可以通过 <code>node</code> 来运行。也就是说，<code>node</code> 就是一个 <code>js</code> 的执行环境</p>
</blockquote>
<h2 id="2-2-HTTP-模块、URL模块"><a href="#2-2-HTTP-模块、URL模块" class="headerlink" title="2.2 HTTP 模块、URL模块"></a>2.2 HTTP 模块、URL模块</h2><blockquote>
<p><code>Node.js</code> 中，将很多的功能，划分为了一个个 <code>module</code>(模块)。 <code>Node.js</code> 中的很多功能都 是通过模块实现</p>
</blockquote>
<h3 id="2-2-1、HTTP-模块的使用"><a href="#2-2-1、HTTP-模块的使用" class="headerlink" title="2.2.1、HTTP 模块的使用"></a>2.2.1、HTTP 模块的使用</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//引用模块</span></span><br><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">"http"</span>);</span><br><span class="line"><span class="comment">//创建一个服务器，回调函数表示接收到请求之后做的事情</span></span><br><span class="line"><span class="keyword">var</span> server = http.createServer(<span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123; <span class="comment">//req 参数表示请求，res 表示响应</span></span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"服务器接收到了请求"</span> + req.url);</span><br><span class="line">    res.end(); <span class="comment">// End 方法使 Web 服务器停止处理脚本并返回当前结果</span></span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">//监听端口</span></span><br><span class="line">server.listen(<span class="number">3000</span>, <span class="string">"127.0.0.1"</span>);</span><br></pre></td></tr></table></figure>
<p><strong>设置一个响应头</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">res.writeHead(<span class="number">200</span>,&#123;<span class="string">"Content-Type"</span>:<span class="string">"text/html;charset=UTF8"</span>&#125;);</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/356.png" alt></p>
<ul>
<li>我们现在来看一下 <code>req</code> 里面能够使用的东西</li>
<li>最关键的就是 <code>req.url</code> 属性，表示用户的请求 <code>URL</code> 地址。所有的路由设计，都是通过 <code>req.url</code> 来实现的。</li>
<li>我们比较关心的不是拿到 <code>URL</code>，而是识别这个 <code>URL</code></li>
<li>识别 <code>URL</code>，用到了下面的 <code>URL</code> 模块</li>
</ul>
<h3 id="2-2-2、URL-模块的使用"><a href="#2-2-2、URL-模块的使用" class="headerlink" title="2.2.2、URL 模块的使用"></a>2.2.2、URL 模块的使用</h3><ul>
<li><code>url.parse()</code>  解析<code>URL</code></li>
<li><code>url.format(urlObject)</code> 是上面 <code>url.parse()</code> 操作的逆向操作</li>
<li><code>url.resolve(from, to)</code> 添加或者替换地址</li>
</ul>
<p><strong>1. url.parse()</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/357.png" alt></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/358.png" alt></p>
<p><strong>2. url.format()</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/359.png" alt></p>
<p><strong>3. url.resolve()</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/360.png" alt></p>
<h2 id="2-3-Nodejs-自启动工具-supervisor"><a href="#2-3-Nodejs-自启动工具-supervisor" class="headerlink" title="2.3 Nodejs 自启动工具 supervisor"></a>2.3 Nodejs 自启动工具 supervisor</h2><blockquote>
<p><code>supervisor</code> 会不停的 <code>watch</code> 你应用下面的所有文件，发现有文件被修改，就重新载入程序文件这样就实现了部署，修改了程序文件后马上就能看到变更后的结果。麻麻再也不用担心我的重启 <code>nodejs</code> 了</p>
</blockquote>
<p><strong>首先安装 supervisor</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install -g supervisor</span><br></pre></td></tr></table></figure>
<p><strong>使用 supervisor 代替 node 命令启动应用</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/361.png" alt></p>
<h1 id="三、CommonJs-和-Nodejs-模块"><a href="#三、CommonJs-和-Nodejs-模块" class="headerlink" title="三、CommonJs 和 Nodejs 模块"></a>三、CommonJs 和 Nodejs 模块</h1><h2 id="3-1-什么是-CommonJs"><a href="#3-1-什么是-CommonJs" class="headerlink" title="3.1 什么是 CommonJs"></a>3.1 什么是 CommonJs</h2><blockquote>
<p><code>JavaScript</code> 是一个强大面向对象语言，它有很多快速高效的解释器。然而， <code>JavaScript</code> 标准定义的 <code>API</code> 是为了构建基于浏览器的应用程序。并没有制定一个用于更广泛的应用程序 的标准库。<br>,而不只是停留在小脚本程序 的阶段。用 <code>CommonJS API</code> 编写出的应用，不仅可以利用 <code>JavaScript</code> 开发客户端应用，而且还可以编写以下应 用 </p>
</blockquote>
<ul>
<li>服务器端 <code>JavaScript</code> 应用程序。(<code>nodejs</code>)</li>
<li>命令行工具</li>
<li>桌面图形界面应用程序</li>
</ul>
<blockquote>
<p><code>CommonJS</code> 就是模块化的标准，<code>nodejs</code> 就是 <code>CommonJS</code>(模块化)的实现</p>
</blockquote>
<h2 id="3-2-Nodejs-中的模块化"><a href="#3-2-Nodejs-中的模块化" class="headerlink" title="3.2 Nodejs 中的模块化"></a>3.2 Nodejs 中的模块化</h2><blockquote>
<p><code>Node</code> 应用由模块组成，采用 <code>CommonJS</code> 模块规范</p>
</blockquote>
<h3 id="3-2-1-在-Node-中，模块分为两类"><a href="#3-2-1-在-Node-中，模块分为两类" class="headerlink" title="3.2.1 在 Node 中，模块分为两类"></a>3.2.1 在 Node 中，模块分为两类</h3><ul>
<li>一类是 <code>Node</code> 提供的模块,称为核心模块;另一类是用户编写的模块，称为文件模块</li>
</ul>
<blockquote>
<ul>
<li>核心模块部分在 <code>Node</code> 源代码的编译过程中，编译进了二进制执行文件。在 <code>Node</code> 进程启动时，部分核心模块就被直接加载进内存中，所以这部分核心模块引入时，文件定位和 编译执行这两个步骤可以省略掉，并且在路径分析中优先判断，所以它的加载速度是最快的。 如:<code>HTTP</code> 模块 、<code>URL</code> 模块、<code>Fs</code> 模块都是 <code>nodejs</code> 内置的核心模块，可以直接引入使用</li>
<li>文件模块则是在运行时动态加载，需要完整的路径分析、文件定位、编译执行过程、速度相比核心模块稍微慢一些，但是用的非常多。这些模块需要我们自己定义。接下来我 们看一下 <code>nodejs</code> 中的自定义模块。</li>
</ul>
</blockquote>
<h3 id="3-2-2-CommonJS-Nodejs-中自定义模块的规定"><a href="#3-2-2-CommonJS-Nodejs-中自定义模块的规定" class="headerlink" title="3.2.2 CommonJS(Nodejs)中自定义模块的规定"></a>3.2.2 CommonJS(Nodejs)中自定义模块的规定</h3><ol>
<li>我们可以把公共的功能抽离成为一个单独的 <code>js</code> 文件作为一个模块，默认情况下面这 个模块里面的方法或者属性，外面是没法访问的。如果要让外部可以访问模块里面的方法或 者属性，就必须在模块里面通过 <code>exports</code> 或者 <code>module.exports</code> 暴露属性或者方法</li>
<li>在需要使用这些模块的文件中，通过 <code>require</code> 的方式引入这个模块。这个时候就可以 使用模块里面暴露的属性和方法</li>
</ol>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/362.png" alt></p>
<h3 id="3-2-3-定义使用模块"><a href="#3-2-3-定义使用模块" class="headerlink" title="3.2.3 定义使用模块"></a>3.2.3 定义使用模块</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 定义一个 tools.js 的模块 //模块定义</span></span><br><span class="line"><span class="keyword">var</span> tools = &#123;</span><br><span class="line">    sayHello: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'hello NodeJS'</span>;</span><br><span class="line">    &#125;,</span><br><span class="line">    add: <span class="function"><span class="keyword">function</span>(<span class="params">x, y</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> x + y;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 模块接口的暴露</span></span><br><span class="line"><span class="comment">// module.exports = tools; exports.sayHello = tools.sayHello; exports.add = tools.add;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">'http'</span>);</span><br><span class="line"><span class="comment">// 引入自定义的 tools.js 模块</span></span><br><span class="line"><span class="keyword">var</span> tools = <span class="built_in">require</span>(<span class="string">'./tools'</span>);</span><br><span class="line"></span><br><span class="line">tools.sa yHello(); <span class="comment">//使用模块</span></span><br></pre></td></tr></table></figure>
<h1 id="四、NPM第三方模块和package"><a href="#四、NPM第三方模块和package" class="headerlink" title="四、NPM第三方模块和package"></a>四、NPM第三方模块和package</h1><h2 id="4-1-包与-NPM"><a href="#4-1-包与-NPM" class="headerlink" title="4.1 包与 NPM"></a>4.1 包与 NPM</h2><h3 id="4-1-1-包"><a href="#4-1-1-包" class="headerlink" title="4.1.1 包"></a>4.1.1 包</h3><blockquote>
<p><code>Nodejs</code> 中除了它自己提供的核心模块外，我们可以自定义模块，也可以使用 第三方的模块。<code>Nodejs</code> 中第三方模块由包组成，可以通过包来对一组具有相互依 赖关系的模块进行统一管理</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/363.png" alt></p>
<p><strong>完全符合 CommonJs 规范的包目录一般包含如下这些文件</strong></p>
<ul>
<li><code>package.json</code> :包描述文件</li>
<li><code>bin</code> :用于存放可执行二进制文件的目录</li>
<li><code>lib</code> :用于存放 <code>JavaScript</code> 代码的目录</li>
<li><code>doc</code> :用于存放文档的目录</li>
</ul>
<blockquote>
<p>在 <code>NodeJs</code> 中通过 <code>NPM</code> 命令来下载第三方的模块(包)</p>
</blockquote>
<h3 id="4-1-2-NPM-介绍"><a href="#4-1-2-NPM-介绍" class="headerlink" title="4.1.2 NPM 介绍"></a>4.1.2 NPM 介绍</h3><ul>
<li>npm 是世界上最大的开放源代码的生态系统。我们可以通过 npm 下载各种各样的包，<br>这些源代码(包)我们可以在 <a href="https://www.npmjs.com" target="_blank" rel="noopener">https://www.npmjs.com</a> 找到</li>
</ul>
<blockquote>
<p><code>npm</code> 是随同 <code>NodeJS</code> 一起安装的包管理工具，能解决 <code>NodeJS</code> 代码部署上的很多问题，常见的使用场景有 以下几种</p>
</blockquote>
<ul>
<li>允许用户从 <code>NPM</code> 服务器下载别人编写的第三方包到本地使用</li>
<li>允许用户从 <code>NPM</code> 服务器下载并安装别人编写的命令行程序(工具)到本地使用</li>
<li>允许用户将自己编写的包或命令行程序上传到 <code>NPM</code> 服务器供别人使用</li>
</ul>
<p><strong>NPM 命令详解</strong></p>
<ul>
<li><code>npm -v</code> 查看 <code>npm</code> 版本</li>
<li><code>npm install</code> 使用 <code>npm</code> 命令安装模块</li>
<li><code>npm uninstall moudleName</code> 卸载模块</li>
<li><code>npm list</code> 查看当前目录下已安装的 <code>node</code> 包</li>
<li><code>npm info jquery</code> 查看 <code>jquery</code> 的版本</li>
<li>指定版本安装 <code>npm install jquery@1.8.0</code></li>
</ul>
<h2 id="4-2-package-json"><a href="#4-2-package-json" class="headerlink" title="4.2 package.json"></a>4.2 package.json</h2><blockquote>
<p><code>package.json</code> 定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、<br>版本、许可证等元数据)</p>
</blockquote>
<p><strong>1. 创建 package.json</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm init</span><br><span class="line">npm init –yes</span><br></pre></td></tr></table></figure>
<p><strong>2. 安装模块并把模块写入 package.json(依赖)</strong></p>
<ul>
<li><code>npm install babel-cli --save-dev</code></li>
<li><code>npm install 模块 --save</code></li>
</ul>
<p><strong>3. dependencies 与 devDependencies 之间的区别</strong></p>
<ul>
<li>使用 <code>npm install node_module –save</code> 自动更新 <code>dependencies</code> 字段值;</li>
<li>使用 <code>npm install node_module –save-dev</code> 自动更新 <code>devDependencies</code> 字段值</li>
<li><code>dependencies</code> 配置当前程序所依赖的其他</li>
<li><code>devDependencies</code> 配置当前程序所依赖的其他包，只会下载模块，而不下载这些模块的测试 和文档框架</li>
</ul>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&quot;dependencies&quot;: &#123;</span><br><span class="line">    &quot;ejs&quot;: &quot;^2.3.4&quot;,</span><br><span class="line">    &quot;express&quot;: &quot;^4.13.3&quot;,</span><br><span class="line">    &quot;formidable&quot;: &quot;^1.0.17&quot;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><code>^</code>表示第一位版本号不变，后面两位取最新的 </li>
<li><code>~</code>表示前两位不变，最后一个取最新 </li>
<li><code>*</code>表示全部取最新</li>
</ul>
<h2 id="4-3-安装淘宝镜像"><a href="#4-3-安装淘宝镜像" class="headerlink" title="4.3 安装淘宝镜像"></a>4.3 安装淘宝镜像</h2><ul>
<li><a href="http://www.npmjs.org" target="_blank" rel="noopener">http://www.npmjs.org</a> npm 包官网</li>
<li><a href="https://npm.taobao.org/" target="_blank" rel="noopener">https://npm.taobao.org/</a> 淘宝 npm 镜像官网</li>
</ul>
<blockquote>
<p>淘宝 <code>NPM</code> 镜像是一个完整 <code>npmjs.org</code> 镜像，你可以用此代替官方版本(只读)，同步频 率目前为 10 分钟 一次以保证尽量与官方服务同步</p>
</blockquote>
<p>我们可以使用我们定制的 <code>cnpm</code> (<code>gzip</code> 压缩支持) 命令行工具代替默认的 <code>npm</code>:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install -g cnpm --registry=https://registry.npm.taobao.org</span><br></pre></td></tr></table></figure>
<h1 id="五、fs模块"><a href="#五、fs模块" class="headerlink" title="五、fs模块"></a>五、fs模块</h1><h2 id="5-1-fs-stat-检测是文件还是目录"><a href="#5-1-fs-stat-检测是文件还是目录" class="headerlink" title="5.1 fs.stat 检测是文件还是目录"></a>5.1 fs.stat 检测是文件还是目录</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>)</span><br><span class="line"></span><br><span class="line">fs.stat(<span class="string">'hello.js'</span>, (error, stats) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(stats) </span><br><span class="line">        </span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">`文件: $ &#123;</span></span><br><span class="line"><span class="string">            stats.isFile()</span></span><br><span class="line"><span class="string">        &#125;`</span>) </span><br><span class="line">        </span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">`目录: $ &#123;</span></span><br><span class="line"><span class="string">            stats.isDirectory()</span></span><br><span class="line"><span class="string">        &#125;`</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-2-fs-mkdir-创建目录"><a href="#5-2-fs-mkdir-创建目录" class="headerlink" title="5.2 fs.mkdir 创建目录"></a>5.2 fs.mkdir 创建目录</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>) </span><br><span class="line"></span><br><span class="line">fs.mkdir(<span class="string">'logs'</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'成功创 建目录:logs'</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-3-fs-writeFile-创建写入文件"><a href="#5-3-fs-writeFile-创建写入文件" class="headerlink" title="5.3 fs.writeFile 创建写入文件"></a>5.3 fs.writeFile 创建写入文件</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">fs.writeFile(<span class="string">'logs/hello.log'</span>, <span class="string">'您好 ~ \n'</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'成功写 入文件'</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-4-fs-appendFile-追加文件"><a href="#5-4-fs-appendFile-追加文件" class="headerlink" title="5.4 fs.appendFile 追加文件"></a>5.4 fs.appendFile 追加文件</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">fs.appendFile(<span class="string">'logs/hello.log'</span>, <span class="string">'hello ~ \n'</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'成功写 入文件'</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-5-fs-readFile-读取文件"><a href="#5-5-fs-readFile-读取文件" class="headerlink" title="5.5 fs.readFile 读取文件"></a>5.5 fs.readFile 读取文件</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>) </span><br><span class="line"></span><br><span class="line">fs.readFile(<span class="string">'logs/hello.log'</span>, <span class="string">'utf8'</span>, (error, data) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(data)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-6-fs-readdir-读取目录"><a href="#5-6-fs-readdir-读取目录" class="headerlink" title="5.6 fs.readdir 读取目录"></a>5.6 fs.readdir 读取目录</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>) </span><br><span class="line"></span><br><span class="line">fs.readdir(<span class="string">'logs'</span>, (error, files) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(files)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-7-fs-rename-重命名"><a href="#5-7-fs-rename-重命名" class="headerlink" title="5.7 fs.rename 重命名"></a>5.7 fs.rename 重命名</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>) </span><br><span class="line"></span><br><span class="line">fs.rename(<span class="string">'js/hello.log'</span>, <span class="string">'js/greeting.log'</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">' 重命名成功'</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-8-fs-rmdir-删除目录"><a href="#5-8-fs-rmdir-删除目录" class="headerlink" title="5.8 fs.rmdir 删除目录"></a>5.8 fs.rmdir 删除目录</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">fs.rmdir(<span class="string">'logs'</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'成功的删除了目录:logs'</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-9-fs-unlink-删除文件"><a href="#5-9-fs-unlink-删除文件" class="headerlink" title="5.9 fs.unlink 删除文件"></a>5.9 fs.unlink 删除文件</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">fs.unlink(<span class="string">`logs / $ &#123;</span></span><br><span class="line"><span class="string">    file</span></span><br><span class="line"><span class="string">&#125;`</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(error)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">`成功的删除了文件: $ &#123;</span></span><br><span class="line"><span class="string">            file</span></span><br><span class="line"><span class="string">        &#125;`</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-10-fs-createReadStream-从文件流中读取数据"><a href="#5-10-fs-createReadStream-从文件流中读取数据" class="headerlink" title="5.10 fs.createReadStream 从文件流中读取数据"></a>5.10 fs.createReadStream 从文件流中读取数据</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>) </span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> fileReadStream = fs.createReadStream(<span class="string">'data.json'</span>) </span><br><span class="line"><span class="keyword">let</span> count = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">var</span> str = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">fileReadStream.on(<span class="string">'data'</span>, (chunk) = &gt;&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">`$ &#123;++count</span></span><br><span class="line"><span class="string">    &#125;接收到: $ &#123;</span></span><br><span class="line"><span class="string">        chunk.length</span></span><br><span class="line"><span class="string">    &#125;`</span>);</span><br><span class="line">    str += chunk</span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">fileReadStream.on(<span class="string">'end'</span>, () = &gt;&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'--- 结束 ---'</span>);</span><br><span class="line">    <span class="built_in">console</span>.log(coun t);</span><br><span class="line">    <span class="built_in">console</span>.log(str);</span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">fileReadStream.on(<span class="string">'error'</span>, (error) = &gt;&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(error)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="5-11-fs-createWriteStream-写入文件"><a href="#5-11-fs-createWriteStream-写入文件" class="headerlink" title="5.11 fs.createWriteStream 写入文件"></a>5.11 fs.createWriteStream 写入文件</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">"fs"</span>);</span><br><span class="line"><span class="keyword">var</span> data = <span class="string">'我是从数据库获取的数据，我要保存起来'</span>;</span><br><span class="line"><span class="comment">// 创建一个可以写入的流，写入到文件 output.txt 中</span></span><br><span class="line"><span class="keyword">var</span> writerStream = fs.createWriteStream(<span class="string">'output.txt'</span>); <span class="comment">// 使用 utf8 编码写入数据</span></span><br><span class="line"></span><br><span class="line">writerStream.write(data, <span class="string">'UTF8'</span>); <span class="comment">// 标记文件末尾</span></span><br><span class="line">writerStream.end();</span><br><span class="line"><span class="comment">// 处理流事件 --&gt; finish 事件</span></span><br><span class="line">writerStream.on(<span class="string">'finish'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">/*finish - 所有数据已被写入到底层系统时触发。*/</span></span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"写入完 成。"</span>);</span><br><span class="line">&#125;);</span><br><span class="line">writerStream.on(<span class="string">'error'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">err</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(err.stack);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"程序执 行完毕"</span>);</span><br></pre></td></tr></table></figure>
<h2 id="5-12-管道流"><a href="#5-12-管道流" class="headerlink" title="5.12 管道流"></a>5.12 管道流</h2><blockquote>
<p>管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/364.png" alt></p>
<blockquote>
<p>如上面的图片所示，我们把文件比作装水的桶，而水就是文件里的内容 ，我们用一根管子(pipe )连接两个桶使得水从一个桶流入另一个桶，这样就慢慢的实现了大文件的复制过程。</p>
</blockquote>
<p>以下实例我们通过读取一个文件内容并将内容写入到另外一个文件中</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">"fs"</span>);</span><br><span class="line"><span class="comment">// 创建一个可读流</span></span><br><span class="line"><span class="keyword">var</span> readerStream = fs.createReadStream(<span class="string">'input.txt'</span>); <span class="comment">// 创建一个可写流</span></span><br><span class="line"><span class="keyword">var</span> writerStream = fs.createWriteStream(<span class="string">'output.txt'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 管道读写操作</span></span><br><span class="line"><span class="comment">// 读取 input.txt 文件内容，并将内容写入到 output.txt 文件中 </span></span><br><span class="line">readerStream.pipe(writerStream);</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"程 序执行完毕"</span>);</span><br></pre></td></tr></table></figure>
<h1 id="六、创建一个-WEB-服务器"><a href="#六、创建一个-WEB-服务器" class="headerlink" title="六、创建一个 WEB 服务器"></a>六、创建一个 WEB 服务器</h1><blockquote>
<p>利用HTTP模块 URl模块 PATH模块 FS 模块创建一个 WEB 服务器</p>
</blockquote>
<p><strong>1. Node.js 创建的第一个应用</strong></p>
<blockquote>
<p>引入 http 模块</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">"http"</span>);</span><br></pre></td></tr></table></figure>
<p><strong>2. 创建服务器</strong></p>
<blockquote>
<p>接下来我们使用 <code>http.createServer()</code> 方法创建服务器，并使用 <code>listen</code> 方法绑定 <code>8888</code> 端口。 函数通过 <code>request</code>, <code>response</code> 参数来接收和响应数据</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//1.引入 http 模块</span></span><br><span class="line"><span class="keyword">var</span> http=<span class="built_in">require</span>(<span class="string">'http'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//2.用 http 模块创建服务</span></span><br><span class="line">http.createServer(fun ction(req, res) &#123;</span><br><span class="line">    <span class="comment">// 发送 HTTP 头部</span></span><br><span class="line">    <span class="comment">// HTTP 状态值: 200 : OK</span></span><br><span class="line">    <span class="comment">//设置 HTTP 头部，状态码是 200，文件类型是 html，字符集是 utf-8</span></span><br><span class="line">    res.writeHead(<span class="number">200</span>, &#123;</span><br><span class="line">        <span class="string">"Content-Type"</span>: <span class="string">"text/html;charset='utf-8'"</span></span><br><span class="line">    &#125;);</span><br><span class="line">    res.write(<span class="string">'你好 nodejs'</span>);</span><br><span class="line">    res.write(<span class="string">'我是第一个 nodejs 程序'</span>);</span><br><span class="line">    res.end();</span><br><span class="line">    <span class="comment">/*结束响应*/</span></span><br><span class="line">&#125;).listen(<span class="number">8001</span>);</span><br></pre></td></tr></table></figure>
<p><strong>3. WEB 服务器介绍</strong></p>
<blockquote>
<p>Web 服务器一般指网站服务器，是指驻留于因特网上某种类型计算机的程序，可以向浏览 器等 Web 客户端提供文档，也可以放置网站文件，让全世界浏览;可以放置数据文件，让 全世界下载。目前最主流的三个 Web 服务器是 Apache Nginx IIS。</p>
</blockquote>
<h1 id="七、Nodejs-的非阻塞-I-O、异步、事件驱动"><a href="#七、Nodejs-的非阻塞-I-O、异步、事件驱动" class="headerlink" title="七、Nodejs 的非阻塞 I/O、异步、事件驱动"></a>七、Nodejs 的非阻塞 I/O、异步、事件驱动</h1><h2 id="7-1-Nodejs的单线程-非阻塞I-O事件驱动"><a href="#7-1-Nodejs的单线程-非阻塞I-O事件驱动" class="headerlink" title="7.1 Nodejs的单线程 非阻塞I/O事件驱动"></a>7.1 Nodejs的单线程 非阻塞I/O事件驱动</h2><ul>
<li>在 Java、PHP 或者.net 等服务器端语言中，会为每一个客户端连接创建一个新的线程。 而每个线程需要耗费大约 2MB 内存。也就是说，理论上，一个 8GB 内存的服务器可以同时 连接的最大用户数为 4000 个左右。要让 Web 应用程序支持更多的用户，就需要增加服务器 的数量，而 Web 应用程序的硬件成本当然就上升了</li>
<li>Node.js 不为每个客户连接创建一个新的线程，而仅仅使用一个线程。当有用户连接了， 就触发一个内部事件，通过非阻塞 I/O、事件驱动机制，让 Node.js 程序宏观上也是并行的。 使用 Node.js，一个 8GB 内存的服务器，可以同时处理超过 4 万用户的连接。</li>
</ul>
<h2 id="7-2-Nodejs-回调处理异步"><a href="#7-2-Nodejs-回调处理异步" class="headerlink" title="7.2 Nodejs 回调处理异步"></a>7.2 Nodejs 回调处理异步</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//错误的写法:</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getData</span>(<span class="params"></span>)</span>&#123; </span><br><span class="line">    <span class="comment">//模拟请求数据 </span></span><br><span class="line">    <span class="keyword">var</span> result=<span class="string">''</span>;</span><br><span class="line">    setTimeout(functio n ()&#123; </span><br><span class="line">        result=<span class="string">'这是请求到的 数据'</span></span><br><span class="line">    &#125;,<span class="number">200</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> result; </span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span> .log(getData());<span class="comment">/*异步导致请求不到数据*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//正确的处理异步:</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getData</span>(<span class="params">callback</span>) </span>&#123; <span class="comment">//模拟请求数据</span></span><br><span class="line">    <span class="keyword">var</span> result = <span class="string">''</span>;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        result = <span class="string">'这是请求到的 数据'</span>;</span><br><span class="line">        callback(result);</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="number">200</span>);</span><br><span class="line">&#125;</span><br><span class="line">getData(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(data);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="7-3-Nodejs-events-模块处理异步"><a href="#7-3-Nodejs-events-模块处理异步" class="headerlink" title="7.3 Nodejs events 模块处理异步"></a>7.3 Nodejs events 模块处理异步</h2><blockquote>
<p><code>Node.js</code> 有多个内置的事件，我们可以通过引入 <code>events</code> 模块，并通过实例化 <code>EventEmitter</code> 类来绑定和监听事件。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 引入 events 模块</span></span><br><span class="line"><span class="keyword">var</span> events = <span class="built_in">require</span>(<span class="string">'events'</span>);</span><br><span class="line"><span class="keyword">var</span> Even tEmitter =<span class="keyword">new</span> event s .EventEmitter() ; <span class="comment">/*实例化事件对象*/</span></span><br><span class="line">EventEmitter.on(<span class="string">'toparent'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123; <span class="built_in">console</span>.log(<span class="string">'接收到了广播事件'</span>);</span><br><span class="line">&#125;)</span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'广播'</span>);</span><br><span class="line">    EventEmitter.emit(<span class="string">'toparent'</span> ); <span class="comment">/*发送广播*/</span> </span><br><span class="line">&#125;,<span class="number">1000</span>)</span><br></pre></td></tr></table></figure>
<h1 id="八、静态文件托管-GET-POST路由EJS模板引擎"><a href="#八、静态文件托管-GET-POST路由EJS模板引擎" class="headerlink" title="八、静态文件托管 GET POST路由EJS模板引擎"></a>八、静态文件托管 GET POST路由EJS模板引擎</h1><h2 id="8-1-路由"><a href="#8-1-路由" class="headerlink" title="8.1 路由"></a>8.1 路由</h2><blockquote>
<p>路由指的就是针对不同请求的 URL，处理不同的业务逻辑。</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/365.png" alt></p>
<h2 id="8-2-初识-EJS-模块引擎"><a href="#8-2-初识-EJS-模块引擎" class="headerlink" title="8.2 初识 EJS 模块引擎"></a>8.2 初识 EJS 模块引擎</h2><blockquote>
<p>我们学的 EJS 是后台模板，可以把我们数据库和文件读取的数据显示到 Html 页面上面。它 是一个第三方模块，需要通过 npm 安装</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install ejs –save / cnpm install ejs --save</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Nodejs 中使用:</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">ejs.renderFile(filename, data, options, <span class="function"><span class="keyword">function</span>(<span class="params">err, str</span>)</span>&#123;</span><br><span class="line"><span class="comment">// str =&gt; Rendered HTML string</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>EJS 常用标签</strong></p>
<ul>
<li><code>&lt;%%&gt;</code>流程控制标签</li>
<li><code>&lt;%=%&gt;</code>输出标签(原文输出HTML标签)</li>
<li><code>&lt;%-%&gt;</code>输出标签(HTML会被浏览器解析)</li>
</ul>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"&lt;%= url %&gt;"</span>&gt;</span><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">"&lt;%= imageURL %&gt;"</span> <span class="attr">alt</span>=<span class="string">""</span>&gt;</span><span class="tag">&lt;/<span class="name">a</span>&gt;</span><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">head</span>&gt;</span><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">    <span class="symbol">&amp;lt;</span>% for(var i = 0 ; i <span class="symbol">&amp;lt;</span> news.length ; i++)&#123; %<span class="symbol">&amp;gt;</span> </span><br><span class="line">   <span class="tag">&lt;<span class="name">li</span>&gt;</span><span class="symbol">&amp;lt;</span>%= news[i] %<span class="symbol">&amp;gt;</span><span class="tag">&lt;/<span class="name">li</span>&gt;</span> <span class="symbol">&amp;lt;</span>% &#125; %<span class="symbol">&amp;gt;</span> </span><br><span class="line">  <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="8-3-Get、Post"><a href="#8-3-Get、Post" class="headerlink" title="8.3 Get、Post"></a>8.3 Get、Post</h2><ul>
<li>超文本传输协议(HTTP)的设计目的是保证客户端机器与服务器之间的通信</li>
<li>在客户端和服务器之间进行请求-响应时，两种最常被用到的方法是:GET 和 POST<ul>
<li>GET - 从指定的资源请求数据。(一般用于获取数据)</li>
<li>POST - 向指定的资源提交要被处理的数据。(一般用于提交数据)</li>
</ul>
</li>
</ul>
<p><strong>获取 GET 传值:</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> urlinfo=url.parse(req.url,<span class="literal">true</span>); </span><br><span class="line">urlinfo.query();</span><br></pre></td></tr></table></figure>
<p><strong>获取 POST 传值:</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> postData = <span class="string">''</span>; </span><br><span class="line"></span><br><span class="line"><span class="comment">// 数据块接收中</span></span><br><span class="line">req.on(<span class="string">'data'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">postDataChunk</span>) </span>&#123;</span><br><span class="line">    postData += postDataChunk;</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 数据接收完毕，执行回调函数</span></span><br><span class="line">req.on(<span class="string">'end'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        postData = <span class="built_in">JSON</span>.parse(postData);</span><br><span class="line">    &#125; <span class="keyword">catch</span>(e) &#123;&#125;</span><br><span class="line">    req.query = postData;</span><br><span class="line">    <span class="built_in">console</span>.log(q uerystring.parse(postData));</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h1 id="九、MongoDb-数据库介绍、安装、使用"><a href="#九、MongoDb-数据库介绍、安装、使用" class="headerlink" title="九、MongoDb 数据库介绍、安装、使用"></a>九、MongoDb 数据库介绍、安装、使用</h1><h2 id="9-1-数据库和文件的主要区别"><a href="#9-1-数据库和文件的主要区别" class="headerlink" title="9.1 数据库和文件的主要区别"></a>9.1 数据库和文件的主要区别</h2><ul>
<li>数据库有数据库表、行和列的概念，让我们存储操作数据更方便</li>
<li>数据库提供了非常方便的接口，可以让 <code>nodejs</code>、<code>php</code> <code>java</code> <code>.net</code> 很方便的实现增加修改删除功能</li>
</ul>
<h2 id="9-2-NoSql-介绍"><a href="#9-2-NoSql-介绍" class="headerlink" title="9.2 NoSql 介绍"></a>9.2 NoSql 介绍</h2><h3 id="9-2-1-NoSQL-介绍"><a href="#9-2-1-NoSQL-介绍" class="headerlink" title="9.2.1 NoSQL 介绍"></a>9.2.1 NoSQL 介绍</h3><ul>
<li>由于互联网的迅速发展，云计算与 Web2.0。这样大量的交互给数据库提出了更高的性能要<br>求，传统的数据库(本文泛指 SQL 数据库)，即关系数据库虽然具备良好的事物管理，<br>但在 处理大量数据 的应用 时很难 在性能 上满足 设计要 求。NoSQL 就是主要为了解决当下大量高并发高要求的数据 库应用 需求，关系数 据库 具有严 格的参 照性，一致性 ，可用 性，原子性 ，隔离 性等特 点</li>
<li>因此会产生一些例如表连接等操作，这样会大大降低系统的性能。而在当前很多应用场景下对性能的要求 远远强 于传统 数据库 关注的 点，<code>NoSQL</code>就是为了解决大规模数据与多样数 据种类 等问题，尤其是其中大数据的相关问题。 </li>
<li><code>NoSQL</code>(<code>NoSQL = Not Only SQL</code> )，意即“不仅仅是 SQL”，它指的是非关系型的数据库，是以 <code>key-value</code><br>形式存储，和传统的关系型数据库不一样，不一定遵循传统数据库的一些基本要求，比如说遵循SQL 标准ACID 属性、表结构等等。<code>NoSQL</code> 最早被提出是在 20 世纪 80 年代，在当时更多是强调的是与关系数据库区 别对待 ，最近这些年被提及的更多是强调协助解决大数据等相关问题。<code>NoSQL</code> 在大数据时代有自己的意义</li>
</ul>
<h3 id="9-2-2-NoSQL-应用情况介绍"><a href="#9-2-2-NoSQL-应用情况介绍" class="headerlink" title="9.2.2 NoSQL 应用情况介绍"></a>9.2.2 NoSQL 应用情况介绍</h3><blockquote>
<p>国内的互联网蓬勃发展，不仅涌现出 BAT(百度，阿里巴巴，腾讯)之类的巨头，也带动了整个互联 网行业的发展，大量的创业型公司如春笋般的涌出，在国家层面也提出了“互联网+”和“万众创业”的口 号。更多传统的行业也开始拥抱互联网。但是无论是做所谓的生态平台还是 传统业务的转型，涉及到的业务是多种多样的。这个时候企业架构师对于应用系统的核心——数据库管理 不仅有传统的 SQL 选项也有了 NoSQL这种适合特定场景需求的选项</p>
</blockquote>
<p><strong>NoSQL 数据库在以下的这几种情况下比较适用</strong></p>
<ul>
<li>数据模型比较简单</li>
<li>需要灵活性更强的 IT 系统</li>
<li>对数据库性能要求较高</li>
<li>不需要高度的数据一致性</li>
<li>对于给定 key，比较容易映射复杂值的环境</li>
</ul>
<p><strong>NoSQL 发展现状</strong></p>
<ul>
<li>国外: Google 的 BigTable 和 Amazon 的 Dynamo 使用的就是 NoSQL 型数据库。</li>
<li>国内:百度、阿里、腾讯、新浪微博、视觉中国、优酷运营数据分析、飞信空间、豆瓣社区等</li>
</ul>
<h2 id="9-3-什么时候建议使用-NoSql"><a href="#9-3-什么时候建议使用-NoSql" class="headerlink" title="9.3 什么时候建议使用 NoSql"></a>9.3 什么时候建议使用 NoSql</h2><ul>
<li>对数据库高并发读写的需求</li>
<li>对海量数据的高效率存储和访问的需求</li>
<li>对数据库的高可扩展性和高可用性的需求</li>
</ul>
<h2 id="9-4-NoSql-和传统数据库简单对比"><a href="#9-4-NoSql-和传统数据库简单对比" class="headerlink" title="9.4 NoSql 和传统数据库简单对比"></a>9.4 NoSql 和传统数据库简单对比</h2><ul>
<li>非结构型数据库。没有行、列的概念。用 JSON 来存储数据。</li>
<li>集合就相当于“表 ”，文档就相当于“行”。</li>
</ul>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/366.png" alt></p>
<h2 id="9-5-NoSql-种类"><a href="#9-5-NoSql-种类" class="headerlink" title="9.5 NoSql 种类"></a>9.5 NoSql 种类</h2><p><img src="https://poetries1.gitee.io/img-repo/2019/10/367.png" alt></p>
<h2 id="9-6-MongoDb-介绍"><a href="#9-6-MongoDb-介绍" class="headerlink" title="9.6 MongoDb 介绍"></a>9.6 MongoDb 介绍</h2><blockquote>
<p>MongoDB 是一个介于关系数据库和非关系数据库之间的产品，是非关系数据库当中功能最丰富，最像 关系数据库的。他支持的数据结构非常松散，是类似 json 的 bson 格式，因此可以存储比较复杂的数据类 型。Mongo 最大的特点是他支持的查询语言非常强大，其语法有点类似于面向对象的查询语言，几乎可以 实现类似关系数据库单表查询的绝大部分功能，而且还支持对数据建立索引。它的特点是高 性能 、易部署 、 易使用 ，存储数据非常 方便 </p>
</blockquote>
<h2 id="9-7-MongoDb-安装"><a href="#9-7-MongoDb-安装" class="headerlink" title="9.7 MongoDb 安装"></a>9.7 MongoDb 安装</h2><ul>
<li>官网:<a href="https://www.mongodb.com/" target="_blank" rel="noopener">https://www.mongodb.com/</a></li>
<li>手册:<a href="https://docs.mongodb.org/manual/" target="_blank" rel="noopener">https://docs.mongodb.org/manual/</a></li>
</ul>
<p><strong>1. 双击 MongoDB 软件下一步下一步安装</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/368.png" alt></p>
<p><strong>2. 安装完成配置环境变量 C:\Program Files\MongoDB\Server\3.0\bin 加入到系统的path 环境变量中</strong></p>
<p><strong>3. 打开 cmd 输入 :mongo命令看看是否成功。如果出来下图说明 mongodb配置成功。</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/369.png" alt></p>
<h2 id="9-8-使用-MongoDb"><a href="#9-8-使用-MongoDb" class="headerlink" title="9.8 使用 MongoDb"></a>9.8 使用 MongoDb</h2><ol>
<li>新建一个存放数据库的文件夹，注意:不能有中文和空格，建议不要放在 C 盘</li>
<li>启动 MongoDb 服务</li>
</ol>
<blockquote>
<p>服务端:<code>mongod</code> 开启数据库服务 <code>mongod --dbpath C:\mongodb</code></p>
</blockquote>
<p><strong>开启 MongoDb 服务命令:</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/370.png" alt></p>
<ul>
<li><code>--dbpath</code> 就是选择数据库文档所在的文件夹</li>
<li>也就是说，<code>mongoDB</code> 中，真的有物理文件，对应一个个数据库。U 盘可以拷走。</li>
<li>注意:一定要保持，开机这个 CMD 不能动了，不能关，不能 <code>ctrl+c</code>。 一旦这个 <code>cmd</code> 有问题了，数据库就自动关闭了</li>
</ul>
<ol start="3">
<li>客户端输入 <code>mongo</code> 命令连接服务端</li>
</ol>
<blockquote>
<p>客户端:<code>mongo</code> 使用数据库</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/371.png" alt></p>
<blockquote>
<p>客户端:<code>mongo</code> 使用数据库 <code>ip</code> 地址:端口号</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/372.png" alt></p>
<h1 id="十、MongoDB-数据库创建删除、表（集合）创建删除、数据增删改查"><a href="#十、MongoDB-数据库创建删除、表（集合）创建删除、数据增删改查" class="headerlink" title="十、MongoDB 数据库创建删除、表（集合）创建删除、数据增删改查"></a>十、MongoDB 数据库创建删除、表（集合）创建删除、数据增删改查</h1><h2 id="10-1-数据库使用"><a href="#10-1-数据库使用" class="headerlink" title="10.1 数据库使用"></a>10.1 数据库使用</h2><blockquote>
<p> 开启 <code>mongodb</code> 服务:要管理数据库，必须先开启服务，开启服务使用 <code>mongod --dbpath c:\mongodb</code></p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/373.png" alt></p>
<blockquote>
<p>管理 <code>mongodb</code> 数据库:<code>mongo</code> (一定要在新的 <code>cmd</code> 中输入)</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/374.png" alt></p>
<blockquote>
<p>查看所有数据库列 表</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">show dbs</span><br></pre></td></tr></table></figure>
<h2 id="10-2-创建数据库"><a href="#10-2-创建数据库" class="headerlink" title="10.2 创建数据库"></a>10.2 创建数据库</h2><p><img src="https://poetries1.gitee.io/img-repo/2019/10/375.png" alt></p>
<p><strong>使用数据库、创建 数据库</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">use student</span><br></pre></td></tr></table></figure>
<ul>
<li>如果真的想把这个数据库创建成功，那么必须插入一个数据</li>
<li>数据库中不能直接插入数据，只能往集合(collectio ns)中插入数 据。不需要专门创建集合，只需要写点语法插入数据就会创建集合:</li>
</ul>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.student.insert(&#123;“name”:”x iaom ing”&#125;);</span><br></pre></td></tr></table></figure>
<ul>
<li>db.student 系统发现 student 是一个陌生的集合名字，所以就自动创建了集合</li>
</ul>
<p><strong>显示当前的数据集合(mysql 中叫表)</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">show collections</span><br></pre></td></tr></table></figure>
<p><strong>删除数据库，删除当前所在的数据库</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.dropDatabase();</span><br></pre></td></tr></table></figure>
<p><strong>删除集合，删除指定的集合删除表</strong></p>
<blockquote>
<p>删除集合 </p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.COLLECTION_NAME.drop()</span><br><span class="line"></span><br><span class="line">db.user.drop()</span><br></pre></td></tr></table></figure>
<h2 id="10-3-插入-增加-数据"><a href="#10-3-插入-增加-数据" class="headerlink" title="10.3 插入(增加)数据"></a>10.3 插入(增加)数据</h2><blockquote>
<p>插入数据，随着数据的插入，数据库创建成功了，集合也创建成功了。</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.表名.insert(&#123;&quot;name&quot;:&quot;zhangsan&quot;&#125;);</span><br><span class="line"></span><br><span class="line">student 集合名称(表)</span><br></pre></td></tr></table></figure>
<h2 id="10-4-查找数据"><a href="#10-4-查找数据" class="headerlink" title="10.4 查找数据"></a>10.4 查找数据</h2><p><strong>1. 查询所有记 录</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find();</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select* from userInfo;</code></p>
</blockquote>
<p><strong>2. 查询去掉后 的当前聚集集合中的某列的重复数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.distinct(&quot;name&quot;);</span><br></pre></td></tr></table></figure>
<ul>
<li>会过滤掉 <code>name</code> 中的相同数据</li>
<li>相当于:<code>select distict name from userInfo;</code></li>
</ul>
<p><strong>3. 查询 age = 22 的记录</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;&quot;age&quot;: 22&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于: <code>select * from userInfo where age = 22;</code></p>
</blockquote>
<p><strong>4. 查询 age &gt; 22 的记录</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$gt: 22&#125;&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select * from userInfo where age &gt;22;</code></p>
</blockquote>
<p><strong>5. 查询 age &lt; 22 的记录</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$lt: 22&#125;&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select * from userInfo where age &lt;22;</code></p>
</blockquote>
<p><strong>6. 查询 age &gt;= 25 的记录</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$gte: 25&#125;&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select * from userInfo where age &gt;= 25;</code></p>
</blockquote>
<p><strong>7. 查询 age &lt;= 25 的记录</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$lte: 25&#125;&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>8. 查询 age &gt;= 23 并且 age &lt;= 26</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$gte: 23, $lte: 26&#125;&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>9. 查询name中包含 mongo的数据,模糊查询用于搜索</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;name: /mongo/&#125;);</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">//相当于%%</span><br><span class="line">select * from userInfo where name like ‘%mongo%’;</span><br></pre></td></tr></table></figure>
<p><strong>10. 查询 name 中以 mongo 开头的</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;name: /^mongo/&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>select * from userInfo where name like ‘mongo%’;</code></p>
</blockquote>
<p><strong>11. 查询指定列 name、age 数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;&#125;, &#123;name: 1, age: 1&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select name, age from userInfo;</code></p>
</blockquote>
<blockquote>
<p>当然 <code>name</code> 也可以用 <code>true</code> 或 <code>false</code>,当用 <code>ture</code> 的情况下河 <code>name:1</code> 效果一样，如果用 <code>false</code> 就 是排除 <code>name</code>，显示 <code>name</code> 以外的列信息</p>
</blockquote>
<p><strong>12. 查询指定列 name、age 数据, age &gt; 25</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$gt: 25&#125;&#125;, &#123;name: 1, age: 1&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select name, age from userInfo where age &gt;25;</code></p>
</blockquote>
<p><strong>13. 按照年龄排序 1 升序 -1 降序</strong></p>
<ul>
<li>升序:<code>db.userInfo.find().sort({age: 1});</code></li>
<li>降序:<code>db.userInfo.find().sort({age: -1});</code></li>
</ul>
<p><strong>14. 查询 name = zhangsan, age = 22 的数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;name: &apos;zhangsan&apos;, age: 22&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select * from userInfo where name = ‘zhangsan’ and age = ‘22’;</code></p>
</blockquote>
<p><strong>15. 查询前 5 条数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find().limit(5 );</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>selecttop 5 * from userInfo;</code></p>
</blockquote>
<p><strong>16. 查询 10 条以后的数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find().skip(10);</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">// 相当于:</span><br><span class="line">select * from userInfo where id not in ( </span><br><span class="line">    selecttop 10 * from userInfo</span><br><span class="line">);</span><br></pre></td></tr></table></figure>
<p><strong>17. 查询在 5-10 之间的数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find().limit (10).skip(5);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>可用于分页，<code>limit</code> 是 <code>pageSize</code>，<code>skip</code> 是第几页<code>*pageSize</code></p>
</blockquote>
<p><strong>18. or与 查询</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;$or: [&#123;age: 22&#125;, &#123;age: 25&#125;]&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select * from userInfo where age = 22 or age = 25;</code></p>
</blockquote>
<p><strong>19. findOne 查询第一条数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.findOne( );</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>selecttop 1 * from userInfo;</code></p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find().limit(1 );</span><br></pre></td></tr></table></figure>
<p><strong>20. 查询某 个结果集的记录条数 统计数量</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.userInfo.find(&#123;age: &#123;$gte: 25&#125;&#125;).count();</span><br></pre></td></tr></table></figure>
<blockquote>
<p>相当于:<code>select count(*) from userInfo where age &gt;= 20;</code></p>
</blockquote>
<blockquote>
<p>如果要返回限制之后的记录数量，要使用 <code>count(true)</code>或者 <code>count</code>(非 <code>0</code>)</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.users.find().skip(1 0).limit(5).count(true);</span><br></pre></td></tr></table></figure>
<h2 id="10-5-修改数据"><a href="#10-5-修改数据" class="headerlink" title="10.5 修改数据"></a>10.5 修改数据</h2><blockquote>
<p>修改里面还有查询条件。你要该谁，要告诉 <code>mongo</code></p>
</blockquote>
<p><strong>查找名字叫做小明的，把年龄更改为 16 岁</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.student.update(&#123;&quot;name&quot;:&quot;小明&quot;&#125;,&#123;$set:&#123;&quot;ag e&quot;:16&#125;&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>查找数学成绩是 70，把年龄更改为 33 岁:</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.student.update(&#123;&quot;sc ore.shuxue&quot;:70&#125;,&#123;$set:&#123;&quot;ag e&quot;:33&#125;&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>更改所有匹配项目</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.student.update(&#123;&quot;sex&quot;:&quot;男&quot;&#125;,&#123;$set:&#123;&quot;age&quot;:33&#125;&#125;,&#123;multi: true&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>完整替换，不出现$set 关键字了: 注意</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.student.update(&#123;&quot;name&quot;:&quot;小明&quot;&#125;,&#123;&quot;name&quot;:&quot;大明&quot;,&quot;age&quot;:16&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>db.users.update({name: &#39;Lisi&#39;}, {$inc: {age: 50}}, false, true);</code> 相当于:<code>update users set age = age + 50 where name = ‘Lisi’;</code></p>
</blockquote>
<blockquote>
<p><code>db.users.update({name: &#39;Lisi&#39;}, {$inc: {age: 50}, $set: {name: &#39;hoho&#39;}}, false, true);</code> 相当于: <code>update users set age = age + 50, name = ‘hoho’ where name = ‘Lisi’;</code></p>
</blockquote>
<h2 id="10-6-删除数据"><a href="#10-6-删除数据" class="headerlink" title="10.6 删除数据"></a>10.6 删除数据</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.collectionsNames.remove( &#123; &quot;borough&quot;: &quot;Manhattan&quot; &#125; )</span><br><span class="line"></span><br><span class="line">db.users.remove(&#123;age: 132&#125;);</span><br><span class="line"></span><br><span class="line">db.restaurants.remove( &#123; &quot;borough&quot;: &quot;Queens&quot; &#125;, &#123; justOne: true &#125; )</span><br></pre></td></tr></table></figure>
<h1 id="十一、MongoDB-索引-explain-分析查询速度"><a href="#十一、MongoDB-索引-explain-分析查询速度" class="headerlink" title="十一、MongoDB 索引 explain 分析查询速度"></a>十一、MongoDB 索引 explain 分析查询速度</h1><h2 id="11-1-索引基础"><a href="#11-1-索引基础" class="headerlink" title="11.1 索引基础"></a>11.1 索引基础</h2><blockquote>
<p>索引是对数据库表中一列或多列的值进行排序的一种结构，可以让我们查询数据库变得 更快。MongoDB 的索引几乎与传统的关系型数据库一模一样，这其中也包括一些基本的查 询优化技巧。</p>
</blockquote>
<p><strong>下面是创建索引的 命令</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex( &#123;&quot;username&quot;:1&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>获取当前集合的索 引</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.getIndexes()</span><br></pre></td></tr></table></figure>
<p><strong>删除索引的命令是</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.dropIndex( &#123;&quot;username&quot;:1&#125;)</span><br></pre></td></tr></table></figure>
<ul>
<li>在 MongoDB 中，我们同样可以创建复合索引，如:</li>
<li>数字 <code>1</code> 表示 <code>username</code> 键的索引按升序存储，<code>-1</code> 表示 <code>age</code> 键的索引按照降序方式存储</li>
</ul>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex(&#123;&quot;username&quot;:1, &quot;age&quot;:-1&#125;)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>该索引被创建后，基于 username 和 age 的查询将会用到该索引，或者是基于 username 的查询也会用到该索引，但是只是基于 age 的查询将不会用到该复合索引。因此可以说，如果想用到复合索引，必须在查询条件中包含复合索引中的前 N个索引列。然而如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话，MongoDB 可以智能的帮助我们调整该顺序，以便使复合索引可以为查询所用。如:</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.find(&#123;&quot;age&quot;: 30, &quot;username&quot;: &quot;stephen&quot;&#125;)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>对于上面示例中的查询条件，MongoDB 在检索之前将会动态的调整查询条件文档的顺 序，以使该查询可以用到刚刚创建的复合索引。</p>
</blockquote>
<blockquote>
<p>对于上面创建的索引，MongoDB 都会根据索引的 keyname 和索引方向为新创建的索引自动分配一个索引名，下面的命令可以在创建索引时为其指定索引名，如:</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex( &#123;&quot;username&quot;:1&#125;,&#123;&quot;name&quot;:&quot;userindex&quot;&#125;)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>随着集合的增长，需要针对查询中大量的排序做索引。如果没有对索引的键调用 <code>sort</code>， <code>MongoDB</code> 需要将所有数据提取到内存并排序。因此在做无索引排序时，如果数据量过大以 致无法在内存中进行排序，此时 <code>MongoDB</code> 将会报错</p>
</blockquote>
<h2 id="11-2-唯一索引"><a href="#11-2-唯一索引" class="headerlink" title="11.2 唯一索引"></a>11.2 唯一索引</h2><blockquote>
<p>在缺省情况下创建的索引均不是唯一索引。下面的示例将创建唯一索引，如</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex( &#123;&quot;useri d&quot;:1&#125;,&#123;&quot;uniq ue&quot;:true&#125;)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>如果再次插入 userid 重复的文档时，MongoDB 将报错，以提示插入重复键，如:</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.insert(&#123;&quot;userid&quot;:5&#125;) </span><br><span class="line">db.user.insert(&#123;&quot;userid&quot;:5&#125;)</span><br><span class="line"></span><br><span class="line">// E11000 duplicate key error index: user.user.$userid_1 dup key: &#123; : 5.0 &#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>如果插入的文档中不包含 userid 键，那么该文档中该键的值为 null，如果多次插入类似 的文档，MongoDB 将会报出同样的错误，如:</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.insert(&#123;&quot;userid1&quot;:5&#125;) </span><br><span class="line">db.user.insert(&#123;&quot;userid1&quot;:5&#125;)</span><br><span class="line"></span><br><span class="line">// E11000 duplicate key error index: user.user.$userid_1 dup key: &#123; : null &#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>如果在创建唯一索引时已经存在了重复项，我们可以通过下面的命令帮助我们在创建唯 一索引时消除重复文档，仅保留发现的第一个文档，如:</p>
</blockquote>
<p><strong>先删除刚刚创建的唯一索引</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.dropIndex( &#123;&quot; userid&quot; :1&#125; )</span><br></pre></td></tr></table></figure>
<p><strong>插入测试数据，以保证集合中有重复键存在。</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.remove() </span><br><span class="line">db.user.insert(&#123;&quot;userid&quot;:5&#125;)</span><br><span class="line">db.user.insert(&#123;&quot;userid&quot;:5&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>重新创建唯一索引</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex(&#123;&quot;userid&quot;:1&#125;,&#123;&quot;unique&quot;:true &#125;)</span><br></pre></td></tr></table></figure>
<p><strong>我们同样可以创建 复合唯一索引，即保证复合键值唯一 即可。如:</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex( &#123;&quot;useri d&quot;:1,&quot;age&quot;:1&#125;,&#123;&quot;unique&quot;:true&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="11-3-索引的一些参数"><a href="#11-3-索引的一些参数" class="headerlink" title="11.3 索引的一些参数"></a>11.3 索引的一些参数</h2><p><img src="https://upload-images.jianshu.io/upload_images/1480597-450216a694af3946.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<blockquote>
<p>如果在为已有数据的文档创建索引时，可以执行下面的命令，以使 MongoDB 在后台创 建索引，这样的创建时就不会阻塞其他操作。但是相比而言，以阻 塞方式创建索引，会使整 个创建过程效率更高，但是在创建时 MongoDB 将无法接收其他的操作</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.user.ensureIndex( &#123;&quot;username&quot;:1&#125;,&#123;&quot;backgroun d&quot;:true&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="11-4-使用-explain"><a href="#11-4-使用-explain" class="headerlink" title="11.4 使用 explain"></a>11.4 使用 explain</h2><blockquote>
<p>explain 是非常有用的工具，会帮助你获得查询方面诸多有用的信息。只要对游标调用 该方法，就可以得到查询细节。explain 会返回一个文档，而不是游标本身。如</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/376.png" alt></p>
<blockquote>
<p><code>explain</code> 会返回查询使用的索引情况，耗时和扫描文档数的统计信息</p>
</blockquote>
<h2 id="11-5-explain-executionStats-查询具体的执行-时间"><a href="#11-5-explain-executionStats-查询具体的执行-时间" class="headerlink" title="11.5 explain executionStats 查询具体的执行 时间"></a>11.5 explain executionStats 查询具体的执行 时间</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">db.tablename.find().explain( &quot;executionStats&quot; )</span><br></pre></td></tr></table></figure>
<blockquote>
<p>关注输出的如下数值:<code>explain.executionStats.executionTimeMillis</code></p>
</blockquote>
<h1 id="十二、nodejs操作mongodb3-x数据库的方法"><a href="#十二、nodejs操作mongodb3-x数据库的方法" class="headerlink" title="十二、nodejs操作mongodb3.x数据库的方法"></a>十二、nodejs操作mongodb3.x数据库的方法</h1><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">//http://mongodb.github.io/node-mongodb-native/3.0/quick-start/quick-start/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">nodejs操作mongodb数据库</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> 1.安装mongodb、</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    cnpm install mongodb --save</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> 2.引入mongodb下面的MongoClient</span></span><br><span class="line"><span class="comment">    var MongoClient = require('mongodb').MongoClient;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> 3.定义数据库连接的地址 以及配置数据库</span></span><br><span class="line"><span class="comment">    qianfeng数据库的名称</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    var url = 'mongodb://localhost:27017/';</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    var dbName = 'shop'</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> 4.nodejs连接数据库</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> MongoClient.connect(url,function(err,client)&#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">        const db = client.db(dbName);  数据库db对象</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> &#125;)</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">5.操作数据库</span></span><br><span class="line"><span class="comment">    </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	 MongoClient.connect(url,function(err,client)&#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">			const db = client.db(dbName);  数据库db对象</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">			MongoClient.connect(url,function(err,db)&#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">				db.collection('user').insertOne(&#123;"name":"张三"&#125;,function(err,result)&#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">					db.close() //关闭连接</span></span><br><span class="line"><span class="comment">				&#125;)</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">		     &#125;)</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	 &#125;)</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">var</span> MongoClient = <span class="built_in">require</span>(<span class="string">'mongodb'</span>).MongoClient;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//定义连接数据库的地址</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span>  url = <span class="string">'mongodb://localhost:27017/'</span>;</span><br><span class="line"><span class="keyword">var</span> dbName = <span class="string">'shop'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//连接数据库</span></span><br><span class="line">MongoClient.connect(url,(err,client)=&gt;&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(err)&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'数据连接失败'</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">let</span> db=client.db(dbName);   <span class="comment">/*获取db对象*/</span></span><br><span class="line"></span><br><span class="line">    db.collection(<span class="string">"admin"</span>).insertOne(&#123;<span class="string">"name"</span>:<span class="string">"mongodb3.0"</span>,<span class="string">"age"</span>:<span class="number">10</span>&#125;,<span class="function"><span class="keyword">function</span>(<span class="params">err</span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(err)&#123;</span><br><span class="line">            <span class="built_in">console</span>.log(<span class="string">'增加失败'</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'增加成功'</span>);</span><br><span class="line">        client.close();  <span class="comment">/*关闭数据库*/</span></span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h1 id="十三、NodeJs操作MongoDb数据库-数据的增加-修改-删除"><a href="#十三、NodeJs操作MongoDb数据库-数据的增加-修改-删除" class="headerlink" title="十三、NodeJs操作MongoDb数据库 数据的增加 修改 删除"></a>十三、NodeJs操作MongoDb数据库 数据的增加 修改 删除</h1><h2 id="13-1-在-Nodejs-中使用-Mongodb"><a href="#13-1-在-Nodejs-中使用-Mongodb" class="headerlink" title="13.1 在 Nodejs 中使用 Mongodb"></a>13.1 在 Nodejs 中使用 Mongodb</h2><blockquote>
<p>前面的课程我们讲了用命令操作 <code>MongoDB</code>，这里我们看下如何用 <code>nodejs</code> 来操作数据库</p>
</blockquote>
<p><strong>需要引包</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install mongodb --save-dev / cnpm install mongodb --save-dev</span><br></pre></td></tr></table></figure>
<h2 id="13-2-Nodejs-连接-MongoDb-数据库"><a href="#13-2-Nodejs-连接-MongoDb-数据库" class="headerlink" title="13.2 Nodejs 连接 MongoDb 数据库"></a>13.2 Nodejs 连接 MongoDb 数据库</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">"express"</span>); <span class="comment">//数据库引用</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> MongoClient = <span class="built_in">require</span>(<span class="string">'mongodb'</span>).MongoClient;</span><br><span class="line"><span class="keyword">var</span> app = express();</span><br><span class="line"><span class="comment">//数据库连接的地址，最后的斜杠表示数据库名字</span></span><br><span class="line"><span class="keyword">var</span> shujukuURL = <span class="string">'mongodb://localhost:27017/news'</span>;</span><br><span class="line">app.get(<span class="string">"/"</span>, fu nction(req, res) &#123; <span class="comment">//连接数据库，这是一个异步的操作</span></span><br><span class="line">    MongoClient.connect(shujukuURL,</span><br><span class="line">    <span class="function"><span class="keyword">function</span>(<span class="params">err, db</span>) </span>&#123;</span><br><span class="line">        res.writeHe ad(<span class="number">200</span>, &#123;</span><br><span class="line">            <span class="string">"Content-Type"</span>: <span class="string">" text/html;charset =UTF8"</span></span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="keyword">if</span> (err) &#123;</span><br><span class="line">            res.send(<span class="string">"数据库连接失 败"</span>);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        res.write(<span class="string">"恭喜，数据库已经成功连接 \n"</span>);</span><br><span class="line">        db.collection(<span class="string">"user"</span>).insertOne(&#123;</span><br><span class="line">            <span class="string">"name"</span>: <span class="string">"哈哈"</span></span><br><span class="line">        &#125;,</span><br><span class="line">        functio n(err, result) &#123;</span><br><span class="line">            <span class="keyword">if</span> (err) &#123;</span><br><span class="line">                res.send(<span class="string">"数据库写入 失败"</span>);</span><br><span class="line">                <span class="keyword">return</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            res.write(<span class="string">"恭喜，数据 已经成功插入"</span>);</span><br><span class="line">            res.end();</span><br><span class="line">            <span class="comment">//关闭数据库</span></span><br><span class="line">            db.close();</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.listen(<span class="number">8020</span>);</span><br></pre></td></tr></table></figure>
<h2 id="13-3-Nodejs-查找-MongoDb-数据库集合"><a href="#13-3-Nodejs-查找-MongoDb-数据库集合" class="headerlink" title="13.3 Nodejs 查找 MongoDb 数据库集合"></a>13.3 Nodejs 查找 MongoDb 数据库集合</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">MongoClient.connect(dbUrl,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">err, db</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (err) &#123;</span><br><span class="line">        <span class="comment">/*数据库连接失败*/</span></span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'数据库连接失败'</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> result = [];</span><br><span class="line">    <span class="keyword">var</span> userRel = db.collection(<span class="string">'user'</span>).find();</span><br><span class="line">    <span class="comment">//res.send(userRel);</span></span><br><span class="line">    userRel.each(<span class="function"><span class="keyword">function</span>(<span class="params">err, doc</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (err) &#123;</span><br><span class="line">            res.write(<span class="string">"游标遍历错 误"</span>);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (doc != <span class="literal">null</span>) &#123;</span><br><span class="line">            result.push(doc);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="built_in">console</span>.log(result); <span class="comment">//遍历完毕</span></span><br><span class="line">            db.close();</span><br><span class="line">            res.render(<span class="string">"index"</span>, &#123;</span><br><span class="line">                <span class="string">"result"</span>: result</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="13-4-Nodejs-给-MongoDb-增加数据"><a href="#13-4-Nodejs-给-MongoDb-增加数据" class="headerlink" title="13.4 Nodejs 给 MongoDb 增加数据"></a>13.4 Nodejs 给 MongoDb 增加数据</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">MongoClient.connect(dbUrl,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">err, db</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (err) &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    db.collection(<span class="string">'user'</span>).insertOne(&#123;</span><br><span class="line">        <span class="string">"name"</span>: name,</span><br><span class="line">        <span class="string">"age"</span>: age,</span><br><span class="line">        <span class="string">"score"</span>: &#123;</span><br><span class="line">            <span class="string">"shuxue"</span>: shuxuechengji,</span><br><span class="line">            <span class="string">"yuwen"</span>: yuwenchengji</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="function"><span class="keyword">function</span>(<span class="params">err, result</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (err) &#123;</span><br><span class="line">            <span class="built_in">console</span>.log(<span class="string">'写入数据失败'</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//关闭数据库</span></span><br><span class="line">        db.close();</span><br><span class="line">        <span class="comment">//res.redirect('/add'); res.redirect('/' ); /*路由跳转*/ res.end(); ////res.location('/add')</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="13-5-Nodejs-修改-MongoDb-数据"><a href="#13-5-Nodejs-修改-MongoDb-数据" class="headerlink" title="13.5 Nodejs 修改 MongoDb 数据"></a>13.5 Nodejs 修改 MongoDb 数据</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">MongoClient.connect(dbUrl,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">err, db</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (err) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'数据库连接错误'</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    db.collection(<span class="string">'user'</span>).updateOne(&#123;</span><br><span class="line">        <span class="string">"_id"</span>: ObjectID(id)</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="string">"name"</span>: name,</span><br><span class="line">        <span class="string">"age"</span>: age,</span><br><span class="line">        <span class="string">"score"</span>: &#123;</span><br><span class="line">            <span class="string">"shuxue"</span>: shuxue,</span><br><span class="line">            <span class="string">"yuwen"</span>: yuwen</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="function"><span class="keyword">function</span>(<span class="params">err, results</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(results);</span><br><span class="line">        db.close();</span><br><span class="line">        res.redirect(<span class="string">'/'</span>);</span><br><span class="line">        <span class="comment">/*路由跳转*/</span></span><br><span class="line">        res.end(<span class="string">'end'</span>);</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="13-6-Nodejs-删除-MongoDb-数据"><a href="#13-6-Nodejs-删除-MongoDb-数据" class="headerlink" title="13.6 Nodejs 删除 MongoDb 数据"></a>13.6 Nodejs 删除 MongoDb 数据</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">MongoClient.connect(dbUrl,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">err, db</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (err) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">"数据库连接失败"</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    db.collection(<span class="string">'user'</span>).deleteOne(&#123;</span><br><span class="line">        <span class="string">"_id"</span>: ObjectID(id)</span><br><span class="line">    &#125;,</span><br><span class="line">    func tion(error, result) &#123;</span><br><span class="line">        <span class="keyword">if</span> (error) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'删除数据失败'</span>);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        db.close();</span><br><span class="line">        res.redirect(<span class="string">'/'</span>);</span><br><span class="line">        <span class="comment">/*路由跳转*/</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h1 id="十四、Express-安装和使用"><a href="#十四、Express-安装和使用" class="headerlink" title="十四、Express 安装和使用"></a>十四、Express 安装和使用</h1><h2 id="14-1-Express-简单介绍"><a href="#14-1-Express-简单介绍" class="headerlink" title="14.1 Express 简单介绍"></a>14.1 Express 简单介绍</h2><ul>
<li>Express 是一个基于 Node.js 平台，快速、开放、极简的 web 开发框架</li>
<li>Express 框架是后台的 Node 框架，所以和 jQuery、zepto、yui、bootstrap 都不一个东西。 Express 在后台的受欢迎的程度类似前端的 jQuery，就是企业的事实上的标准。</li>
</ul>
<p><strong>Express 特点</strong></p>
<ul>
<li><code>Express</code> 是一个基于 <code>Node.js</code> 平台的极简、灵活的 web 应用开发框架，它提供一<br>系列强大的特性，帮助你创建各种 <code>Web</code> 和移动设备应用</li>
<li>丰富的 HTTP 快捷方法和任意排列组合的 <code>Connect</code> 中间件，让你创建健壮、友好的 API 变得既快速又简单</li>
<li><code>Express</code> 不对 <code>Node.js</code> 已有的特性进行二次抽象，我们只是在它之上扩展了 Web应用所需的基本功能</li>
</ul>
<h2 id="14-2-Express-安装使用"><a href="#14-2-Express-安装使用" class="headerlink" title="14.2 Express 安装使用"></a>14.2 Express 安装使用</h2><p><strong>安装:</strong></p>
<blockquote>
<p>安装 Express 框架，就是使用 npm 的命令</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install express --save</span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>--save</code> 参数，表示自动修改 <code>package.json</code> 文件，自动添加依赖项</p>
</blockquote>
<p><strong>简单使用</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">npm install express–save <span class="comment">//1.引入</span></span><br><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="keyword">var</span> app = express();</span><br><span class="line"><span class="comment">//2.配置路由</span></span><br><span class="line">app.get(<span class="string">'/'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'Hello World!'</span>);</span><br><span class="line">&#125;); <span class="comment">//3.监听端口</span></span><br><span class="line"></span><br><span class="line">app.listen(<span class="number">3000</span>,<span class="string">'127.0.0.1'</span>);</span><br></pre></td></tr></table></figure>
<p><strong>完整 Demo</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="comment">/*引入 express*/</span></span><br><span class="line"><span class="keyword">var</span> app = newexpress();</span><br><span class="line"><span class="comment">/*实例化express 赋值给app*/</span></span><br><span class="line"><span class="comment">//配置路由 匹配 URl 地址实现不同的功能</span></span><br><span class="line">app.get(<span class="string">'/'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'首页'</span>);</span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">app.get(<span class="string">'/search'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'搜索'</span>); <span class="comment">//?keyword=华为手机&amp;enc=utf-8&amp;suggest=1.his.0.0&amp;wq</span></span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">app.get(<span class="string">'/login'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'登录'</span>);</span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">app.get(<span class="string">'/register'</span>,</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'注册'</span>);</span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">app.listen(<span class="number">3000</span>, <span class="string">"127.0.0.1"</span>);</span><br></pre></td></tr></table></figure>
<h2 id="14-3-Express-框架中的路由"><a href="#14-3-Express-框架中的路由" class="headerlink" title="14.3 Express 框架中的路由"></a>14.3 Express 框架中的路由</h2><blockquote>
<p>路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等) 组成的，涉及到应用如何响应客户端对某个网站节点的访问</p>
</blockquote>
<p><strong>简单的路由配置</strong></p>
<blockquote>
<p>当用 get 请求访问一个网址的时候，做什么事情</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.get(<span class="string">"网址"</span>,<span class="function"><span class="keyword">function</span>(<span class="params">req,res</span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>当用 post 访问一个网址的时候，做什么事情:</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.post(<span class="string">"网址"</span>,<span class="function"><span class="keyword">function</span>(<span class="params">req,res</span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// user 节点接受 PUT 请求</span></span><br><span class="line"></span><br><span class="line">app.put(<span class="string">'/user'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'Got a PUT request at /user'</span>); </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// user 节点接受 DELETE 请求</span></span><br><span class="line"></span><br><span class="line">app.delete(<span class="string">'/user'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.send(<span class="string">'Got a DELETE request at /user'</span>); </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>动态路由配置:</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.get( ,<span class="function"><span class="keyword">function</span>(<span class="params">req,res</span>)</span>&#123; </span><br><span class="line">    <span class="keyword">var</span> id = req.params[<span class="string">"id"</span>];</span><br><span class="line">    res.send(id); </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>路由的正则匹配:(了解)</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.get(<span class="string">'/ab*cd'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123; </span><br><span class="line">    res.send(<span class="string">'ab*cd'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>路由里面获取 Get 传值</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// /news?id=2&amp;sex=nan</span></span><br><span class="line"></span><br><span class="line">app.get(<span class="string">'/news, function(req, res) &#123; </span></span><br><span class="line"><span class="string">    console.log(req.query);</span></span><br><span class="line"><span class="string">&#125;);</span></span><br></pre></td></tr></table></figure>
<h2 id="14-4-Express-框架中-ejs-的安装使用"><a href="#14-4-Express-框架中-ejs-的安装使用" class="headerlink" title="14.4 Express 框架中 ejs 的安装使用"></a>14.4 Express 框架中 ejs 的安装使用</h2><p><strong>Express 中 ejs 的安装:</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install ejs --save </span><br><span class="line"></span><br><span class="line">// 或者:</span><br><span class="line">npm install ejs --save-dev</span><br></pre></td></tr></table></figure>
<p><strong>Express 中 ejs 的使用</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">"express"</span>);</span><br><span class="line"><span class="keyword">var</span> app = express();</span><br><span class="line">app.set(<span class="string">"view engine"</span>, <span class="string">"ejs"</span>);</span><br><span class="line"></span><br><span class="line">app.get(<span class="string">"/"</span>,</span><br><span class="line">    <span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;&#125;);</span><br><span class="line">        res.render(<span class="string">"news"</span>, &#123;</span><br><span class="line">            <span class="string">"news"</span>: [<span class="string">"我是小新闻啊"</span>, <span class="string">"我也是啊"</span>, <span class="string">"哈哈哈哈"</span>]</span><br><span class="line">&#125;);</span><br><span class="line">app.listen(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure>
<p><strong>指定模板位置 ，默认模板位置在 views</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">app.set(&apos;views&apos;, __dirname + &apos;/views&apos;);</span><br></pre></td></tr></table></figure>
<p><strong>Ejs 引入模板</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&lt;%- include header.ejs %&gt;</span><br></pre></td></tr></table></figure>
<p><strong>Ejs 绑定数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&lt;%=h%&gt;</span><br></pre></td></tr></table></figure>
<p><strong>Ejs 绑定 html 数据</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&lt;%-h%&gt;</span><br></pre></td></tr></table></figure>
<p><strong>Ejs 模板判断语句</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&lt;% if(true)&#123; %&gt; </span><br><span class="line">    &lt;div&gt;true&lt;/div&gt;</span><br><span class="line">    &lt;%&#125; </span><br><span class="line">  else&#123; %&gt; </span><br><span class="line">    &lt;div&gt;false&lt; /di v&gt;</span><br><span class="line">&lt;%&#125; %&gt;</span><br></pre></td></tr></table></figure>
<p><strong>Ejs 模板中循环数据</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">&lt;%for(var i=0;i&lt;list.length;i++) &#123; %&gt;</span><br><span class="line">    <span class="tag">&lt;<span class="name">li</span>&gt;</span><span class="tag">&lt;<span class="name">%=list[i]</span> %&gt;</span><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">%&#125;%</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>Ejs 后缀修改为 Html</strong></p>
<blockquote>
<p>这是一个小技巧，看着<code>.ejs</code> 的后缀总觉得不爽，使用如下方法，可以将模板文件的后缀换成我们习惯的<code>.html</code></p>
</blockquote>
<ol>
<li>在 <code>app.js</code> 的头上定义 <code>ejs</code>:,代码如下:</li>
</ol>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">var ejs = require(&apos;ejs&apos;);</span><br></pre></td></tr></table></figure>
<ol start="2">
<li>注册 html 模板引擎代码如下:</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.engine(<span class="string">'html'</span>,ejs.__express);</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>将模板引擎换成 html代码如下:</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.set(<span class="string">'view engine'</span>, <span class="string">'html'</span>);</span><br></pre></td></tr></table></figure>
<ol start="4">
<li>修改模板文件的后缀为 <code>.html</code></li>
</ol>
<h2 id="14-5-利用-Express-static-托管静态文件"><a href="#14-5-利用-Express-static-托管静态文件" class="headerlink" title="14.5 利用 Express.static 托管静态文件"></a>14.5 利用 Express.static 托管静态文件</h2><ol>
<li>如果你的静态资源存放在多个目录下面，你可以多次调用 <code>express.static</code> 中间件:</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.use(express.static(<span class="string">'public'</span>));</span><br></pre></td></tr></table></figure>
<blockquote>
<p>现在，public 目录下面的文件就可以访问了</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">http://localhost:3000/images/kitten.jpg</span><br><span class="line">http://localhost:3000/css/style.css </span><br><span class="line">http://localhost:3000/js/app.js</span><br><span class="line">http://localhost:3000/images/bg.png h</span><br><span class="line">ttp://localhost:3000/hello.html</span><br></pre></td></tr></table></figure>
<ol start="2">
<li>如果你希望所有通过 <code>express.static</code> 访问的文件都存放在一个“虚拟(virtual)”目 录(即目录根本不存在)下面，可以通过为静态资源目录指定一个挂载路径的方式来实现，如下所示</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.use(<span class="string">'/static'</span>, express.static(<span class="string">'public'</span>));</span><br></pre></td></tr></table></figure>
<blockquote>
<p>现在，你就爱可以通过带有 “/static” 前缀的地址来访问 public 目录下 面的文件了</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">http://localhost:3000/static/images/kitten.jpg</span><br><span class="line">http://localhost:3000/static/css/style.css http://localhost:3000/static/js/app.js http://localhost:3000/static/images/bg.png</span><br><span class="line">http://localhost:3000/static/hello.html</span><br></pre></td></tr></table></figure>
<h2 id="14-6-Express-中间件"><a href="#14-6-Express-中间件" class="headerlink" title="14.6 Express 中间件"></a>14.6 Express 中间件</h2><ul>
<li><code>Express</code> 是一个自身功能极简，完全是由路由和中间件构成一个的 web 开发框架:从<br>本质上来说，一个 <code>Express</code> 应用就是在调用各种中间件</li>
<li>中间件(<code>Middleware</code>) 是一个函数，它可以访问请求对象(request object (req)), 响 应对象(response object (res)), 和 web 应用中处理请求-响应循环流程中的中间件，一般 被命名为 next 的变量</li>
</ul>
<p><strong>中间件的功能包括</strong></p>
<ul>
<li>执行任何代码</li>
<li>修改请求和响应对象</li>
<li>终结请求-响应循环</li>
<li>调用堆栈中的下一个中间件</li>
</ul>
<blockquote>
<p>如果我的 <code>get</code>、<code>post</code> 回调函数中，没有 <code>next</code> 参数，那么就匹配上第一个路由，就不会往下匹 配了。如果想往下匹配的话，那么需要写 <code>next()</code></p>
</blockquote>
<p><strong>Express 应用可使用如下几种中间件</strong></p>
<ul>
<li>应用级中间件</li>
<li>路由级中间件</li>
<li>错误处理中间件</li>
<li>内置中间件</li>
<li>第三方中间件</li>
</ul>
<ol>
<li>应用级中间件</li>
</ol>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/377.png" alt></p>
<ol start="2">
<li>路由中间件</li>
</ol>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/378.png" alt></p>
<ol start="3">
<li>错误处理中间件</li>
</ol>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/379.png" alt></p>
<ol start="4">
<li>内置中间件</li>
</ol>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/380.png" alt></p>
<ol start="5">
<li>第三方中间件</li>
</ol>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/381.png" alt><br><img src="https://poetries1.gitee.io/img-repo/2019/10/382.png" alt></p>
<h2 id="14-7-获取-Get-Post-请求的参数"><a href="#14-7-获取-Get-Post-请求的参数" class="headerlink" title="14.7 获取 Get Post 请求的参数"></a>14.7 获取 Get Post 请求的参数</h2><ul>
<li><code>GET</code> 请求的参数在 <code>URL</code> 中，在原生 <code>Node</code> 中，需要使用 <code>url</code> 模块来识别参数字符串。在<code>Express</code> 中，不需要使用 <code>url</code> 模块了。可以直接使用 <code>req.query</code> 对象</li>
<li><code>POST</code> 请求在 <code>express</code> 中不能直接获得，可以使用 <code>body-parser</code> 模块。使用后，将可以用<code>req.body</code>得到参数。但是如果表单中含有文件上传，那么还是需要使用 <code>formidable</code> 模块</li>
</ul>
<p><strong>1. 安装</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm install body-parser</span><br></pre></td></tr></table></figure>
<p><strong>2. 使用 req.body 获取 post 过来的参数</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>) </span><br><span class="line"><span class="keyword">var</span> bodyParser = <span class="built_in">require</span>(<span class="string">'body-parser'</span>) </span><br><span class="line"><span class="keyword">var</span> app = express()</span><br><span class="line"></span><br><span class="line"><span class="comment">// parse application/x-www-form-urlencoded</span></span><br><span class="line">app.use(bodyParser.urlencoded(&#123;</span><br><span class="line">    extended: <span class="literal">false</span></span><br><span class="line">&#125;))</span><br><span class="line"></span><br><span class="line"><span class="comment">// parse application/json</span></span><br><span class="line">app.use(bodyParser.json()) </span><br><span class="line"></span><br><span class="line">app.use(<span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>) </span>&#123;</span><br><span class="line">    res.setHeader(<span class="string">'Content-Type'</span>, <span class="string">'text/plain'</span>) res.write(<span class="string">'you posted:\n'</span>) res.end(<span class="built_in">JSON</span>.stringify(req.body, <span class="literal">null</span>, <span class="number">2</span>))</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h1 id="十五、express中间件cookie的基本使用"><a href="#十五、express中间件cookie的基本使用" class="headerlink" title="十五、express中间件cookie的基本使用"></a>十五、express中间件cookie的基本使用</h1><h2 id="15-1-Cookie-简介"><a href="#15-1-Cookie-简介" class="headerlink" title="15.1 Cookie 简介"></a>15.1 Cookie 简介</h2><p><img src="https://poetries1.gitee.io/img-repo/2019/10/383.png" alt></p>
<h2 id="15-2-Cookie-特点"><a href="#15-2-Cookie-特点" class="headerlink" title="15.2 Cookie 特点"></a>15.2 Cookie 特点</h2><ul>
<li><code>cookie</code> 保存在浏览器本地</li>
<li>正常设置的 <code>cookie</code> 是不加密的，用户可以自由看到;</li>
<li>用户可以删除 <code>cookie</code>，或者禁用它</li>
<li><code>cookie</code> 可以被篡改</li>
<li><code>cookie</code> 可以用于攻击</li>
<li><code>cookie</code> 存储量很小。未来实际上要被 <code>localStorage</code> 替代，但是后者 <code>IE9</code> 兼容</li>
</ul>
<h2 id="15-3-Cookie-的使用"><a href="#15-3-Cookie-的使用" class="headerlink" title="15.3 Cookie 的使用"></a>15.3 Cookie 的使用</h2><p><img src="https://poetries1.gitee.io/img-repo/2019/10/384.png" alt><br><img src="https://poetries1.gitee.io/img-repo/2019/10/385.png" alt><br><img src="https://poetries1.gitee.io/img-repo/2019/10/386.png" alt></p>
<p><strong>设置 cookie</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">res.cookie(<span class="string">'rememberme'</span>, <span class="string">'1'</span>, &#123; <span class="attr">maxAge</span>: <span class="number">900000</span>, <span class="attr">httpOnly</span>: <span class="literal">true</span> &#125;)</span><br><span class="line"></span><br><span class="line">res.cookie(<span class="string">'name'</span>, <span class="string">'tobi'</span>, &#123; <span class="attr">domain</span>: <span class="string">'.example.com'</span>, <span class="attr">path</span>: <span class="string">'/admin'</span>, <span class="attr">secure</span>: <span class="literal">true</span> &#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">res.cookie(<span class="string">'rememberme'</span>, <span class="string">'1'</span>, &#123; <span class="attr">expires</span>: <span class="keyword">new</span> <span class="built_in">Date</span>(<span class="built_in">Date</span>.now() + <span class="number">900000</span>), <span class="attr">httpOnly</span>: <span class="literal">true</span> &#125;);</span><br></pre></td></tr></table></figure>
<p><strong>获取 cookie</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">req.cookies.name</span><br></pre></td></tr></table></figure>
<p><strong>删除 cookie</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">res.cookie(&apos;rememberme&apos;, &apos;&apos;, &#123; expires: new Date(0)&#125;);</span><br><span class="line"></span><br><span class="line">res.cookie(&apos;username&apos;,&apos;zhangsan&apos;,&#123;domain:&apos;.ccc.com&apos;,maxAge:0,httpOnly:true&#125;);</span><br></pre></td></tr></table></figure>
<h2 id="15-4-加密-Cookie"><a href="#15-4-加密-Cookie" class="headerlink" title="15.4 加密 Cookie"></a>15.4 加密 Cookie</h2><p><strong>1. 配置中间件的时候需要传参</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> cookieParser = <span class="built_in">require</span>(<span class="string">'cookie-parser'</span>);</span><br><span class="line"></span><br><span class="line">app.use(cookieParser(<span class="string">'123456'</span>));</span><br></pre></td></tr></table></figure>
<p><strong>2. 设置 cookie 的时候配置 signed 属性</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">res.c ookie(<span class="string">'userinfo'</span>,<span class="string">'hahaha'</span>,&#123;<span class="attr">domain</span>:<span class="string">'.c cc.c om'</span>,<span class="attr">maxAge</span> :<span class="number">900000</span>,<span class="attr">httpOnly</span> :<span class="literal">true</span>,<span class="attr">signed</span> :<span class="literal">true</span>&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>3. signedCookies 调用设置的 cookie</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(req.signedCookies);</span><br></pre></td></tr></table></figure>
<h1 id="十六、express中间件express-session常见参数配置使用"><a href="#十六、express中间件express-session常见参数配置使用" class="headerlink" title="十六、express中间件express-session常见参数配置使用"></a>十六、express中间件express-session常见参数配置使用</h1><h2 id="16-1-Session-简单介绍"><a href="#16-1-Session-简单介绍" class="headerlink" title="16.1 Session 简单介绍"></a>16.1 Session 简单介绍</h2><blockquote>
<p><code>session</code> 是另一种记录客户状态的机制，不同的是 <code>Cookie</code>保存在客户端浏览器中，而 <code>session</code> 保存在服<br>务器上</p>
</blockquote>
<p><strong>Session 的用途</strong></p>
<ul>
<li><code>session</code> 运行在服务器端，当客户端第一次访问服务器时，可以将客户的登录信息保存</li>
<li>当客户访问其他页面时，可以判断客户的登录状态，做出提示，相当于登录拦截</li>
<li><code>session</code> 可以和 <code>Redis</code>或者数据库等结合做持久化操作，当服务器挂掉时也不会导致某些客户信息(购物车)<br>丢失。</li>
</ul>
<h2 id="16-2-Session-的工作流程"><a href="#16-2-Session-的工作流程" class="headerlink" title="16.2 Session 的工作流程"></a>16.2 Session 的工作流程</h2><blockquote>
<p>当浏览器访问服务器并发送第一次请求时，服务器端会创建一个 session 对象，生成一个类似于 key,value 的键值对，然后将 key(cookie)返回到浏览器(客户)端，浏览器下次再访问时，携带 key(cookie)， 找到对应的 session(value)。 客户的信息都保存在 session 中</p>
</blockquote>
<h2 id="16-3-express-session-的使用"><a href="#16-3-express-session-的使用" class="headerlink" title="16.3 express-session 的使用"></a>16.3 express-session 的使用</h2><p><strong>1. 安装 express-session</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cnpm install express-session --save</span><br></pre></td></tr></table></figure>
<p><strong>2. 引入 express-session</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">var session = require(&quot;express-session&quot;);</span><br></pre></td></tr></table></figure>
<p><strong>3. 设置官方文档提供的中间件</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.use(session(&#123;</span><br><span class="line">    secret: <span class="string">'keyboard cat'</span>,</span><br><span class="line">    resave: <span class="literal">true</span>,</span><br><span class="line">    saveUninitialized: <span class="literal">true</span></span><br><span class="line">&#125;))</span><br></pre></td></tr></table></figure>
<p><strong>4. 使用</strong></p>
<ul>
<li>设置值 <code>req.session.username = &quot;张三&quot;;</code></li>
<li>获取值 <code>req.session.username</code></li>
</ul>
<h2 id="16-4-express-session-的常用参数"><a href="#16-4-express-session-的常用参数" class="headerlink" title="16.4 express-session 的常用参数"></a>16.4 express-session 的常用参数</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.use(session(&#123;</span><br><span class="line">    secret: <span class="string">'12345'</span>,</span><br><span class="line">    name: <span class="string">'name'</span>,</span><br><span class="line">    cookie: &#123;</span><br><span class="line">        maxAge: <span class="number">60000</span></span><br><span class="line">    &#125;,</span><br><span class="line">    resave: <span class="literal">false</span>,</span><br><span class="line">    saveUninitialized: <span class="literal">true</span></span><br><span class="line">&#125;));</span><br></pre></td></tr></table></figure>
<p><strong>行加密的字符串.这个</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/387.png" alt><br><img src="https://poetries1.gitee.io/img-repo/2019/10/388.png" alt></p>
<h2 id="16-5-express-session-的常用方法"><a href="#16-5-express-session-的常用方法" class="headerlink" title="16.5 express-session 的常用方法"></a>16.5 express-session 的常用方法</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">req.session.destroy(<span class="function"><span class="keyword">function</span>(<span class="params">err</span>) </span>&#123;</span><br><span class="line">    <span class="comment">/*销毁 session*/</span></span><br><span class="line">&#125;) </span><br><span class="line">req.session.username = <span class="string">'张三'</span>; <span class="comment">//设置 session req.session.username //获取 </span></span><br><span class="line"></span><br><span class="line">session req.session.cookie.maxAge=<span class="number">0</span>; <span class="comment">//重新设置 cookie 的过期时间</span></span><br></pre></td></tr></table></figure>
<h2 id="16-6-负载均衡配置-Session，把-Session-保存到数据库-里面"><a href="#16-6-负载均衡配置-Session，把-Session-保存到数据库-里面" class="headerlink" title="16.6 负载均衡配置 Session，把 Session 保存到数据库 里面"></a>16.6 负载均衡配置 Session，把 Session 保存到数据库 里面</h2><ol>
<li><p>需要安装<code>express-session</code> 和 <code>connect-mongo</code>模块 </p>
</li>
<li><p>引入模块</p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> session = <span class="built_in">require</span>(<span class="string">"express-session"</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> MongoStore = <span class="built_in">require</span>(<span class="string">'connect-mongo'</span>)(session);</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>配置中间件</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">app.use(session(&#123;</span><br><span class="line">    secret: <span class="string">'keyboard cat'</span>,</span><br><span class="line">    resave: <span class="literal">false</span>,</span><br><span class="line">    saveUninitialized: <span class="literal">true</span>,</span><br><span class="line">    rolling:<span class="literal">true</span>,</span><br><span class="line">    cookie:&#123;</span><br><span class="line">        maxAge:<span class="number">100000</span></span><br><span class="line">    &#125;,</span><br><span class="line">    store: <span class="keyword">new</span> MongoStore(&#123;</span><br><span class="line">        url: <span class="string">'mongodb://127.0.0.1:27017/student'</span>,</span><br><span class="line">        touchAfter: <span class="number">24</span> * <span class="number">3600</span> <span class="comment">// time period in seconds</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;))</span><br></pre></td></tr></table></figure>
<h2 id="16-7-Cookie-和-Session-区别"><a href="#16-7-Cookie-和-Session-区别" class="headerlink" title="16.7 Cookie 和 Session 区别"></a>16.7 Cookie 和 Session 区别</h2><ol>
<li><code>cookie</code> 数据存放在客户的浏览器上，<code>session</code> 数据放在服务器上</li>
<li><code>cookie</code> 不是很安全，别人可以分析存放在本地的 <code>COOKIE</code> 并进行 <code>COOKIE</code> 欺骗 考虑到安全应当使用 <code>session</code></li>
<li><code>session</code> 会在一定时间内保存在服务器上。当访问增多，会比较占用你服务器的性能 考虑到减轻服务器性能方面，应当使用 <code>COOKIE</code></li>
<li>单个 <code>cookie</code> 保存的数据不能超过 <code>4K</code>，很多浏览器都限制一个站点最多保存 <code>20</code> 个 <code>cookie</code></li>
</ol>

      </div>
    
  </div>

</article>

<button class="assist-btn2 circle" id="assist_btn2" title="点亮屏幕" style="left: 27px; top: 152px;">
  <i class="iconfont" style="display:inline-block;color:red;width:20px;height:20px;">&#xe61d;</i>
</button>
<button class="assist-btn1 circle" id="assist_btn1" title="关闭屏幕亮度" style="left: 27px; top: 152px;">
  <i class="iconfont toc-title" style="display:inline-block;color:red;width:20px;height:20px;">&#xe61d;</i>
</button>


<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>	

<script src="https://my.openwrite.cn/js/readmore.js" type="text/javascript"></script>
<script>
  const btw = new BTWPlugin();
  btw.init({
    id: "container",
    blogId: "22699-1592137983091-414",
    name: "前端进阶之旅",
    qrcode: "https://poetries1.gitee.io/img-repo/2020/06/qrcode.jpg",
    keyword: "3a3b3c",
  });
</script>

<script type="text/javascript">

// white theme
var body = {color: "#555", background: "#000"};
var a_tag = {color: "#222"};
var header = { background: "#222"};
var logo_line_i = {background: "#222"};
// var post_code = {background: "#eee", color: "#222"};

function switch_theme() {
 $("body").css(body);
 $("a:not('.links-of-author-item a, .site-state-item a, .site-state-posts a, .feed-link a, .motion-element a, .post-tags a, .show-commit-cls a, #donate_board a')").css(a_tag);
 $(".header, .footer").css(header);
 $(".logo-line-before i, .logo-line-after i").css(logo_line_i);
 //$(".post code").css(post_code);
 $("#idhyt-surprise-ball #idhyt-surprise-ball-animation .drag").css(a_tag);
 $(".post-title-link, .posts-expand .post-meta, .post-comments-count, .disqus-comment-count, .post-category a, .post-nav-next a, .post-nav-item a").css(a_tag);
 
 // $("code").css({color: '#c5c8c6', background: '#1d1f21'});
 //$("#assist_btn1").hide(1500);
}

$(function () {
$("#assist_btn2").css("display","none");
 $("#assist_btn1").click(function() {
     switch_theme();
$("div#toc.toc-article").css({
 "background":"#eaeaea",
 "opacity":1
});
$(".toc-article ol").show();
$("#toc.toc-article .toc-title").css("color","#a98602");
$("#assist_btn1").css("display","none");
$("#assist_btn2").css("display","block");
 });
$("#assist_btn2").click(function() {
$("#assist_btn2").css("display","none");
$("#assist_btn1").css("display","block");
$("body").css("background","url(http://www.miaov.com/static/ie/images/news/bg.png)")
     $(".header, .footer").css("background","url(http://www.miaov.com/static/ie/images/news/bg.png)")
$(".toc-article ol").toggle(1000);
 });
});


//背景随机

var Y, O, E, L, B, C, T, z, N, S, A, I;
!function() {
var e = function() {
for (O.clearRect(0, 0, L, B), T = [{
x: 0,
y: .7 * B + C
}, {
x: 0,
y: .7 * B - C
}]; T[1].x < L + C;) t(T[0], T[1])
}, t = function(e, t) {
O.beginPath(), O.moveTo(e.x, e.y), O.lineTo(t.x, t.y);
var n = t.x + (2 * I() - .25) * C,
 r = a(t.y);
O.lineTo(n, r), O.closePath(), N -= S / -50, O.fillStyle = "#" + (127 * A(N) + 128 << 16 | 127 * A(N + S / 3) + 128 << 8 | 127 * A(N + S / 3 * 2) + 128).toString(16), O.fill(), T[0] = T[1], T[1] = {
 x: n,
 y: r
}
}, a = function n(e) {
var t = e + (2 * I() - 1.1) * C;
return t > B || t < 0 ? n(e) : t
};
Y = document.getElementById("evanyou"), O = Y.getContext("2d"), E = window.devicePixelRatio || 1, L = window.innerWidth, B = window.innerHeight, C = 90, z = Math, N = 0, S = 2 * z.PI, A = z.cos, I = z.random, Y.width = L * E, Y.height = B * E, O.scale(E, E), O.globalAlpha = .6, document.onclick = e, document.ontouchstart = e, e()
}()

   
$("#toc-eye").click(function(){
$("#toc.toc-article").toggle(1000);
});

</script>


   
  <div class="text-center donation">
    <div class="inner-donation">
      <span class="btn-donation">支持一下</span>
      <div class="donation-body">
        <div class="tip text-center">扫一扫，支持poetries</div>
        <ul>
        
          <li class="item">
            
              <span>微信扫一扫</span>
            
            <img src="/images/weixin.jpg" alt="">
          </li>
        
          <li class="item">
            
              <span>支付宝扫一扫</span>
            
            <img src="/images/zhifubao.jpg" alt="">
          </li>
        
        </ul>
      </div>
    </div>
  </div>


   
  <div class="box-prev-next clearfix">
    <a class="show pull-left" href="/2019/01/24/node-socketio/">
        <i class="icon icon-angle-left"></i>
    </a>
    <a class="show pull-right" href="/2019/03/09/relearn-koa/">
        <i class="icon icon-angle-right"></i>
    </a>
  </div>




</div>


  <a id="backTop" class="back-top">
    <i class="icon-angle-up"></i>
  </a>




  <div class="modal" id="modal">
  <span id="cover" class="cover hide"></span>
  <div id="modal-dialog" class="modal-dialog hide-dialog">
    <div class="modal-header">
      <span id="close" class="btn-close">关闭</span>
    </div>
    <hr>
    <div class="modal-body">
      <ul class="list-toolbox">
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/archives/"
              rel="noopener noreferrer"
              target="_self"
              >
              博客
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/categories/"
              rel="noopener noreferrer"
              target="_self"
              >
              分类
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/tags/"
              rel="noopener noreferrer"
              target="_self"
              >
              标签
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/search/"
              rel="noopener noreferrer"
              target="_self"
              >
              搜索
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/link/"
              rel="noopener noreferrer"
              target="_self"
              >
              友链
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/about/"
              rel="noopener noreferrer"
              target="_self"
              >
              关于
            </a>
          </li>
        
      </ul>

    </div>
  </div>
</div>



  
      <div class="fexo-comments comments-post">
    

    

    
    

    

    
    

    

<!-- Gitalk评论插件通用代码 -->
<div id="gitalk-container"></div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css">
<script src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js"></script>
<script>
const gitalk = new Gitalk({
  clientID: '5567a2c4abb858009d96',
  clientSecret: 'b9039ec056cf5c2346b3cdb63308a28c163f91e5',
  repo: 'poetries.github.io',
  owner: 'poetries',
  // 在这里设置一下截取前50个字符串, 这是因为 github 对 label 的长度有了要求, 如果超过
  // 50个字符串则会报错.
  // id: location.pathname.split('/').pop().substring(0, 49),
  id: location.pathname,
  admin: ['poetries'],
  // facebook-like distraction free mode
  distractionFreeMode: false
})
gitalk.render('gitalk-container')
</script>
<!-- Gitalk代码结束 -->



  </div>

  

  <script type="text/javascript">
  function loadScript(url, callback) {
    var script = document.createElement('script')
    script.type = 'text/javascript';

    if (script.readyState) { //IE
      script.onreadystatechange = function() {
        if (script.readyState == 'loaded' ||
          script.readyState == 'complete') {
          script.onreadystatechange = null;
          callback();
        }
      };
    } else { //Others
      script.onload = function() {
        callback();
      };
    }

    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
  }

  window.onload = function() {
    loadScript('/js/bundle.js?235683', function() {
      // load success
    });
  }
</script>


  <!-- 页面点击小红心 -->
  <script type="text/javascript" src="/js/clicklove.js"></script>
 
  
</body>
</html>
